/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SATA_HBA_H #define _SATA_HBA_H #ifdef __cplusplus extern "C" { #endif #include /* * SATA Host Bus Adapter (HBA) driver transport definitions */ #include #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define SATA_SUCCESS 0 #define SATA_RETRY 1 #define SATA_FAILURE -1 /* SATA Framework definitions */ #define SATA_MAX_CPORTS 32 /* Max number of controller ports */ /* Multiplier (PMult) */ #define SATA_MAX_PMPORTS 16 /* Maximum number of ports on PMult */ #define SATA_PMULT_HOSTPORT 0xf /* Port Multiplier host port number */ /* * SATA device address * Address qualifier flags are used to specify what is addressed (device * or port) and where (controller or port multiplier data port). */ struct sata_address { uint8_t cport; /* Controller's SATA port number */ uint8_t pmport; /* Port Multiplier SATA port number */ uint8_t qual; /* Address Qualifier flags */ uint8_t pad; /* Reserved */ }; typedef struct sata_address sata_address_t; /* * SATA address Qualifier flags (in qual field of sata_address struct). * They are mutually exclusive. */ #define SATA_ADDR_NULL 0x00 /* No address */ #define SATA_ADDR_DCPORT 0x01 /* Device attched to controller port */ #define SATA_ADDR_DPMPORT 0x02 /* Device attched to PM device port */ #define SATA_ADDR_CPORT 0x04 /* Controller's device port */ #define SATA_ADDR_PMPORT 0x08 /* Port Multiplier's device port */ #define SATA_ADDR_CNTRL 0x10 /* Controller */ #define SATA_ADDR_PMULT 0x20 /* Port Multiplier */ #define SATA_ADDR_PMULT_SPEC 0x40 /* Port Multiplier Specific */ /* * SATA port status and control register block. * The sstatus, serror, scontrol, sactive and snotific * are the copies of the SATA port status and control registers. * (Port SStatus, SError, SControl, SActive and SNotification are * defined by Serial ATA r1.0a sepc and Serial ATA II spec. */ struct sata_port_scr { uint32_t sstatus; /* Port SStatus register */ uint32_t serror; /* Port SError register */ uint32_t scontrol; /* Port SControl register */ uint32_t sactive; /* Port SActive register */ uint32_t snotific; /* Port SNotification register */ }; typedef struct sata_port_scr sata_port_scr_t; /* * SATA Port Multiplier general status and control register block. * The gscr0, gscr1, gscr2 are the copyies of the register on port multiplier. * GSCR[0], GSCR[1], GSCR[2] are defined in SATA defined by Port Multiplier * 1.0/1.1/1.2 spec. */ struct sata_pmult_gscr { uint32_t gscr0; /* Product Identifier register */ uint32_t gscr1; /* Resrved Information register */ uint32_t gscr2; /* Port Information register */ uint32_t gscr64; /* Feature register */ uint32_t resv[4]; /* Reseved */ }; typedef struct sata_pmult_gscr sata_pmult_gscr_t; /* * SATA Device Structure (rev 1) * Used to request/return state of the controller, port, port multiplier * or an attached drive: * The satadev_addr.cport, satadev_addr.pmport and satadev_addr.qual * fields are used to specify SATA address (see sata_address structure * description). * The satadev_scr structure is used to pass the content of a port * status and control registers. * The satadev_add_info field is used by SATA HBA driver to return an * additional information, which type depends on the function using * sata_device as argument. For example: * - in case of sata_tran_probe_port() this field should contain * a number of available Port Multiplier device ports; * - in case of sata_hba_event_notify() this field may contain * a value specific for a reported event. */ #define SATA_DEVICE_REV_1 1 #define SATA_DEVICE_REV SATA_DEVICE_REV_1 struct sata_device { int satadev_rev; /* structure version */ struct sata_address satadev_addr; /* sata port/device address */ uint32_t satadev_state; /* Port or device state */ uint32_t satadev_type; /* Attached device type */ struct sata_port_scr satadev_scr; /* Port status and ctrl regs */ uint32_t satadev_add_info; /* additional information, */ /* function specific */ }; typedef struct sata_device sata_device_t; _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_device)) /* * satadev_state field of sata_device structure. * Common flags specifying current state of a port or an attached drive. * These states are mutually exclusive, obviously */ #define SATA_STATE_UNKNOWN 0x000000 #define SATA_STATE_READY 0x000010 /* * Attached drive specific states (satadev_state field of the sata_device * structure). * SATA_DSTATE_PWR_ACTIVE, SATA_DSTATE_PWR_IDLE and SATA_DSTATE_PWR_STANDBY * are mutually exclusive. All other states may be combined with each other * and with one of the power states. * These flags may be used only if the address qualifier (satadev_addr.qual) is * set to SATA_ADDR_DCPORT or SATA_ADDR_DPMPORT value. */ #define SATA_DSTATE_PWR_ACTIVE 0x000100 #define SATA_DSTATE_PWR_IDLE 0x000200 #define SATA_DSTATE_PWR_STANDBY 0x000400 #define SATA_DSTATE_RESET 0x001000 #define SATA_DSTATE_PMULT_INIT 0x002000 #define SATA_DSTATE_FAILED 0x008000 /* Mask for drive power states */ #define SATA_DSTATE_PWR (SATA_DSTATE_PWR_ACTIVE | \ SATA_DSTATE_PWR_IDLE | \ SATA_DSTATE_PWR_STANDBY) /* * SATA Port specific states (satadev_state field of sata_device structure). * SATA_PSTATE_PWRON and SATA_PSTATE_PWROFF are mutually exclusive. * All other states may be combined with each other and with one of the power * level state. * These flags may be used only if the address qualifier (satadev_addr.qual) is * set to SATA_ADDR_CPORT or SATA_ADDR_PMPORT value. */ #define SATA_PSTATE_PWRON 0x010000 #define SATA_PSTATE_PWROFF 0X020000 #define SATA_PSTATE_SHUTDOWN 0x040000 #define SATA_PSTATE_FAILED 0x080000 /* Mask for the valid port-specific state flags */ #define SATA_PSTATE_VALID (SATA_PSTATE_PWRON | \ SATA_PSTATE_PWROFF | \ SATA_PSTATE_SHUTDOWN | \ SATA_PSTATE_FAILED) /* Mask for a port power states */ #define SATA_PSTATE_PWR (SATA_PSTATE_PWRON | \ SATA_PSTATE_PWROFF) /* * Device type (in satadev_type field of sata_device structure). * More device types may be added in the future. */ #define SATA_DTYPE_NONE 0x00 /* No device attached */ #define SATA_DTYPE_ATADISK 0x01 /* ATA disk */ #define SATA_DTYPE_ATAPI 0x40 /* ATAPI device */ #define SATA_DTYPE_ATAPICD \ (SATA_DTYPE_ATAPI|0x02) /* ATAPI CD/DVD device */ #define SATA_DTYPE_ATAPITAPE \ (SATA_DTYPE_ATAPI|0x04) /* ATAPI tape */ #define SATA_DTYPE_ATAPIDISK \ (SATA_DTYPE_ATAPI|0x08) /* ATAPI disk */ #define SATA_DTYPE_PMULT 0x10 /* Port Multiplier */ #define SATA_DTYPE_UNKNOWN 0x20 /* Device attached, unkown */ #define SATA_DTYPE_ATAPIPROC \ (SATA_DTYPE_ATAPI|0x80) /* ATAPI processor */ /* * SATA cmd structure (rev 1) * * SATA HBA framework always sets all fields except status_reg and error_reg. * SATA HBA driver action depends on the addressing type specified by * addr_type field: * If LBA48 addressing is indicated, SATA HBA driver has to load values from * satacmd_sec_count_msb_reg, satacmd_lba_low_msb_reg, * satacmd_lba_mid_msb_reg and satacmd_lba_hi_msb_reg * to appropriate registers prior to loading other registers. * For other addressing modes, SATA HBA driver should skip loading values * from satacmd_sec_count_msb_reg, satacmd_lba_low_msb_reg, * satacmd_lba_mid_msb_reg and satacmd_lba_hi_msb_reg * fields and load only remaining field values to corresponding registers. * * satacmd_sec_count_msb and satamcd_sec_count_lsb values are loaded into * sec_count register, satacmd_sec_count_msb loaded first (if LBA48 * addressing is used). * satacmd_lba_low_msb and satacmd_lba_low_lsb values are loaded into the * lba_low register, satacmd_lba_low_msb loaded first (if LBA48 addressing * is used). The lba_low register is the newer name for the old * sector_number register. * satacmd_lba_mid_msb and satacmd_lba_mid_lsb values are loaded into lba_mid * register, satacmd_lba_mid_msb loaded first (if LBA48 addressing is used). * The lba_mid register is the newer name for the old cylinder_low register. * satacmd_lba_high_msb and satacmd_lba_high_lsb values are loaded into * the lba_high regster, satacmd_lba_high_msb loaded first (if LBA48 * addressing is used). The lba_high register is a newer name for the old * cylinder_high register. * * No addressing mode is selected when an ata command does not involve actual * reading/writing data from/to the media (for example IDENTIFY DEVICE or * SET FEATURE command), or the ATAPI PACKET command is sent. * If ATAPI PACKET command is sent and tagged commands are used, * SATA HBA driver has to provide and manage a tag value and * set it into the sector_count register. * * Device Control register is not specified in sata_cmd structure - SATA HBA * driver shall set it accordingly to current mode of operation (interrupt * enable/disable). * * Buffer structure's b_flags should be used to determine the * address type of b_un.b_addr. However, there is no need to allocate DMA * resources for the buffer in SATA HBA driver. * DMA resources for a buffer structure are allocated by the SATA HBA * framework. Scatter/gather list is to be used only for DMA transfers * and it should be based on the DMA cookies list. * * Upon completion of a command, SATA HBA driver has to update * satacmd_status_reg and satacmd_error_reg to reflect the contents of * the corresponding device status and error registers. * If the command completed successfully, satacmd_flags.sata_copy_xxx flags * specify what register fields should be updated in sata_cmd structure. * If the command completed with error, SATA HBA driver has to update * satacmd_sec_count_msb, satacmd_sec_count_lsb, satacmd_lba_low_msb, * satacmd_lba_low_lsb, satacmd_lba_mid_msb, satacmd_lba_mid_lsb, * satacmd_lba_high_msb and satacmd_lba_high_lsb to values read from the * corresponding device registers. * If an operation could not complete because of the port error, the * sata_pkt.satapkt_device.satadev_scr structure has to be updated. * * If ATAPI PACKET command was sent and command completed with error, * rqsense structure has to be filed by SATA HBA driver. The satacmd_arq_cdb * points to pre-set request sense cdb that may be used for issuing request * sense data from the device. * * The sata_max_queue_depth field specifies the maximum allowable queue depth * minus one, i.e. for maximum queue depth of 32, sata_max_queue_depth would * be set to value 0x1f. * If FPDMA-type command was sent and command completed with error, the HBA * driver may use pre-set command READ LOG EXTENDED command pointed to * by satacmd_rle_sata_cmd field to retrieve error data from a device. * Only ATA register fields of the sata_cmd are set-up for that purpose. * * If the READ MULTIPLIER command was specified in cmd_reg (command directed * to a port multiplier host port rather then to an attached device), * upon the command completion SATA HBA driver has to update_sector count * and lba fields of the sata_cmd structure to values returned via * command block registers (task file registers). */ #define SATA_CMD_REV_1 1 #define SATA_CMD_REV_2 2 #define SATA_CMD_REV_3 3 #define SATA_CMD_REV SATA_CMD_REV_3 #define SATA_ATAPI_MAX_CDB_LEN 16 /* Covers both 12 and 16 byte cdbs */ #define SATA_ATAPI_RQSENSE_LEN 24 /* Allocated Request Sense data */ #define SATA_ATAPI_MIN_RQSENSE_LEN 18 /* Min Fixed size Request Sense data */ #define SATA_ATAPI_RQSENSE_CDB_LEN 6 /* Request Sense CDB length */ #define SATA_MAX_QUEUE_DEPTH 32 /* Default max queue depth */ struct sata_cmd { int satacmd_rev; /* version */ struct buf *satacmd_bp; /* ptr to buffer structure */ struct sata_cmd_flags { uint32_t sata_data_direction : 3; /* 0-2 */ uint32_t : 1; /* reserved */ /* 3 */ uint32_t sata_queue_stag : 1; /* 4 */ uint32_t sata_queue_otag : 1; /* 5 */ uint32_t : 2; /* reserved */ /* 6-7 */ uint32_t sata_queued : 1; /* 8 */ uint32_t : 3; /* reserved */ /* 9-11 */ uint32_t sata_ignore_dev_reset : 1; /* 12 */ uint32_t sata_clear_dev_reset : 1; /* 13 */ uint32_t : 2; /* reserved */ /* 14-15 */ uint32_t sata_special_regs : 1; /* 16 */ uint32_t sata_copy_out_sec_count_msb : 1; /* 17 */ uint32_t sata_copy_out_lba_low_msb : 1; /* 18 */ uint32_t sata_copy_out_lba_mid_msb : 1; /* 19 */ uint32_t sata_copy_out_lba_high_msb : 1; /* 20 */ uint32_t sata_copy_out_sec_count_lsb : 1; /* 21 */ uint32_t sata_copy_out_lba_low_lsb : 1; /* 22 */ uint32_t sata_copy_out_lba_mid_lsb : 1; /* 23 */ uint32_t sata_copy_out_lba_high_lsb : 1; /* 24 */ uint32_t sata_copy_out_device_reg : 1; /* 25 */ uint32_t sata_copy_out_error_reg : 1; /* 26 */ uint32_t sata_max_queue_depth: 5; /* 27-31 */ } satacmd_flags; uint8_t satacmd_addr_type; /* addr type: LBA28, LBA48 */ uint8_t satacmd_features_reg_ext; /* features reg extended */ uint8_t satacmd_sec_count_msb; /* sector count MSB (LBA48) */ uint8_t satacmd_lba_low_msb; /* LBA Low MSB (LBA48) */ uint8_t satacmd_lba_mid_msb; /* LBA Mid MSB (LBA48) */ uint8_t satacmd_lba_high_msb; /* LBA High MSB (LBA48) */ uint8_t satacmd_sec_count_lsb; /* sector count LSB */ uint8_t satacmd_lba_low_lsb; /* LBA Low LSB */ uint8_t satacmd_lba_mid_lsb; /* LBA Mid LSB */ uint8_t satacmd_lba_high_lsb; /* LBA High LSB */ uint8_t satacmd_device_reg; /* ATA dev reg & LBA28 MSB */ uint8_t satacmd_cmd_reg; /* ata command code */ uint8_t satacmd_features_reg; /* ATA features register */ uint8_t satacmd_status_reg; /* ATA status register */ uint8_t satacmd_error_reg; /* ATA error register */ uint8_t satacmd_acdb_len; /* ATAPI cdb length */ uint8_t satacmd_acdb[SATA_ATAPI_MAX_CDB_LEN]; /* ATAPI cdb */ /* kept for binary compat. */ uint8_t *pad1; /* unused */ uint8_t satacmd_rqsense[SATA_ATAPI_RQSENSE_LEN]; /* * Error retrieval buffer * dma handle pointer * (for buffer DMA syncing) * Valid only in error * retrieval packet! */ ddi_dma_handle_t *satacmd_err_ret_buf_handle; int satacmd_num_dma_cookies; /* number of dma cookies */ /* ptr to dma cookie list */ ddi_dma_cookie_t *satacmd_dma_cookie_list; }; typedef struct sata_cmd sata_cmd_t; _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_cmd)) /* ATA address type (in satacmd_addr_type field */ #define ATA_ADDR_LBA 0x1 #define ATA_ADDR_LBA28 0x2 #define ATA_ADDR_LBA48 0x4 /* * satacmd_flags : contain data transfer direction flags, * tagged queuing type flags, queued command flag, and reset state handling * flag. */ /* * Data transfer direction flags (satacmd_flags.sata_data_direction) * Direction flags are mutually exclusive. */ #define SATA_DIR_NODATA_XFER 0x0001 /* No data transfer */ #define SATA_DIR_READ 0x0002 /* Reading data from a device */ #define SATA_DIR_WRITE 0x0004 /* Writing data to a device */ /* * Tagged Queuing type flags * satacmd_flags.sata_queue_stag * satacmd_flags.sata_queue_otag * * These flags indicate how the SATA command should be queued. * * sata_queue_stag * Simple-queue-tagged command. It may be executed out-of-order in respect * to other queued commands. * sata_queue_otag * Ordered-queue-tagged command. It cannot be executed out-of-order in * respect to other commands, i.e. it should be executed in the order of * being transported to the HBA. * * Translated head-of-queue-tagged scsi commands and commands that are * to be put at the head of the queue are treated as sata_queue_otag * tagged commands. */ /* * Queuing command set-up flag (satacmd_flags.sata_queued). * This flag indicates that sata_cmd was set-up for DMA Queued command * (either READ_DMA_QUEUED, READ_DMA_QUEUED_EXT, WRITE_DMA_QUEUED or * WRITE_DMA_QUEUED_EXT command) or one of the Native Command Queuing commands * (either READ_FPDMA_QUEUED or WRITE_FPDMA_QUEUED). * This flag will be used only if sata_tran_hba_flags indicates controller * support for queuing and the device for which sata_cmd is prepared supports * either legacy queuing (indicated by Device Identify data word 83 bit 2) * or NCQ (indicated by word 76 of Device Identify data). */ /* * Reset state handling * satacmd_flags.sata_ignore_dev_reset * satacmd_flags.sata_clear_dev_reset * * SATA HBA device enters reset state if the device was subjected to * the Device Reset (may also enter this state if the device was reset * as a side effect of port reset). SATA HBA driver sets this state. * Device stays in this condition until explicit request from SATA HBA * framework to clear the state. */ /* * SATA Packet structure (rev 1) * hba_driver_private is for a private use of the SATA HBA driver; * satapkt_framework_private is used only by SATA HBA framework; * satapkt_comp is a callback function to be called when packet * execution is completed (for any reason) if mode of operation is not * synchronous (SATA_OPMODE_SYNCH); * satapkt_reason specifies why the packet operation was completed * * NOTE: after the packet completion callback SATA HBA driver should not * attempt to access any sata_pkt fields because sata_pkt is not valid anymore * (it could have been destroyed). * Since satapkt_hba_driver_private field cannot be retrieved, any hba private * data respources allocated per packet and accessed via this pointer should * either be freed before the completion callback is done, or the pointer has * to be saved by the HBA driver before the completion callback. */ #define SATA_PKT_REV_1 1 #define SATA_PKT_REV SATA_PKT_REV_1 struct sata_pkt { int satapkt_rev; /* version */ struct sata_device satapkt_device; /* Device address/type */ /* HBA driver private data */ void *satapkt_hba_driver_private; /* SATA framework priv data */ void *satapkt_framework_private; /* Rqsted mode of operation */ uint32_t satapkt_op_mode; struct sata_cmd satapkt_cmd; /* composite sata command */ int satapkt_time; /* time allotted to command */ void (*satapkt_comp)(struct sata_pkt *); /* callback */ int satapkt_reason; /* completion reason */ }; typedef struct sata_pkt sata_pkt_t; _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_pkt)) /* * Operation mode flags (in satapkt_op_mode field of sata_pkt structure). * Use to specify what should be a mode of operation for specified command. * Default (000b) means use Interrupt and Asynchronous mode to * perform an operation. * Synchronous operation menas that the packet operation has to be completed * before the function called to initiate the operation returns. */ #define SATA_OPMODE_INTERRUPTS 0 /* Use interrupts (hint) */ #define SATA_OPMODE_POLLING 1 /* Use polling instead of interrupts */ #define SATA_OPMODE_ASYNCH 0 /* Return immediately after accepting pkt */ #define SATA_OPMODE_SYNCH 4 /* Perform synchronous operation */ /* * satapkt_reason values: * * SATA_PKT_QUEUE_FULL - cmd not sent because of queue full (detected * by the controller). If a device reject command for this reason, it * should be reported as SATA_PKT_DEV_ERROR * * SATA_PKT_CMD_NOT_SUPPORTED - command not supported by a controller * Controller is unable to send such command to a device. * If device rejects a command, it should be reported as * SATA_PKT_DEV_ERROR. * * SATA_PKT_DEV_ERROR - cmd failed because of device reported an error. * The content of status_reg (ERROR bit has to be set) and error_reg * fields of the sata_cmd structure have to be set and will be used * by SATA HBA Framework to determine the error cause. * * SATA_PKT_PORT_ERROR - cmd failed because of a link or a port error. * Link failed / no communication with a device / communication error * or other port related error was detected by a controller. * sata_pkt.satapkt_device.satadev_scr.sXXXXXXX words have to be set. * * SATA_PKT_ABORTED - cmd execution was aborted by the request from the * framework. Abort mechanism is HBA driver specific. * * SATA_PKT_TIMEOUT - cmd execution has timed-out. Timeout specified by * pkt_time was exceeded. The command was terminated by the SATA HBA * driver. * * SATA_PKT_COMPLETED - this is a value returned when an operation * completes without errors. * * SATA_PKT_BUSY - packet was not accepted for execution because the * driver was busy performing some other operation(s). * * SATA_PKT_RESET - packet execution was aborted because of device * reset originated by either the HBA driver or the SATA framework. * */ #define SATA_PKT_BUSY -1 /* Not completed, busy */ #define SATA_PKT_COMPLETED 0 /* No error */ #define SATA_PKT_DEV_ERROR 1 /* Device reported error */ #define SATA_PKT_QUEUE_FULL 2 /* Not accepted, queue full */ #define SATA_PKT_PORT_ERROR 3 /* Not completed, port error */ #define SATA_PKT_CMD_UNSUPPORTED 4 /* Cmd unsupported */ #define SATA_PKT_ABORTED 5 /* Aborted by request */ #define SATA_PKT_TIMEOUT 6 /* Operation timeut */ #define SATA_PKT_RESET 7 /* Aborted by reset request */ /* * Error retrieval sata packet types */ #define SATA_ERR_RETR_PKT_TYPE_NCQ 1 #define SATA_ERR_RETR_PKT_TYPE_ATAPI 2 /* * Read/write port multiplier packet types */ #define SATA_RDWR_PMULT_PKT_TYPE_READ 1 #define SATA_RDWR_PMULT_PKT_TYPE_WRITE 2 /* * Hoplug functions vector structure (rev 1) */ #define SATA_TRAN_HOTPLUG_OPS_REV_1 1 struct sata_tran_hotplug_ops { int sata_tran_hotplug_ops_rev; /* version */ int (*sata_tran_port_activate)(dev_info_t *, sata_device_t *); int (*sata_tran_port_deactivate)(dev_info_t *, sata_device_t *); }; typedef struct sata_tran_hotplug_ops sata_tran_hotplug_ops_t; /* * Power management functions vector structure (rev 1) * The embedded function returns information about the controller's * power level. * Additional functions may be added in the future without changes to * sata_tran structure. */ #define SATA_TRAN_PWRMGT_OPS_REV_1 1 struct sata_tran_pwrmgt_ops { int sata_tran_pwrmgt_ops_rev; /* version */ int (*sata_tran_get_pwr_level)(dev_info_t *, sata_device_t *); }; typedef struct sata_tran_pwrmgt_ops sata_tran_pwrmgt_ops_t; /* * SATA port PHY Power Level * These states correspond to the interface power management state as defined * in Serial ATA spec. */ #define SATA_TRAN_PORTPWR_LEVEL1 1 /* Interface in active PM state */ #define SATA_TRAN_PORTPWR_LEVEL2 2 /* Interface in PARTIAL PM state */ #define SATA_TRAN_PORTPWR_LEVEL3 3 /* Interface in SLUMBER PM state */ /* * SATA HBA Tran structure (rev 1) * Registered with SATA Framework * * dma_attr is a pointer to data (buffer) dma attibutes of the controller * DMA engine. * * The qdepth field specifies number of commands that may be accepted by * the controller. Value range 1-32. A value greater than 1 indicates that * the controller supports queuing. Support for Native Command Queuing * indicated by SATA_CTLF_NCQ flag also requires qdepth set to a value * greater then 1. * */ #define SATA_TRAN_HBA_REV_1 1 #define SATA_TRAN_HBA_REV_2 2 #define SATA_TRAN_HBA_REV_3 3 #define SATA_TRAN_HBA_REV SATA_TRAN_HBA_REV_3 struct sata_hba_tran { int sata_tran_hba_rev; /* version */ dev_info_t *sata_tran_hba_dip; /* Controler dev info */ ddi_dma_attr_t *sata_tran_hba_dma_attr; /* DMA attributes */ int sata_tran_hba_num_cports; /* Num of HBA device ports */ uint16_t sata_tran_hba_features_support; /* HBA features */ uint16_t sata_tran_hba_qdepth; /* HBA-supported queue depth */ int (*sata_tran_probe_port)(dev_info_t *, sata_device_t *); int (*sata_tran_start)(dev_info_t *, sata_pkt_t *); int (*sata_tran_abort)(dev_info_t *, sata_pkt_t *, int); int (*sata_tran_reset_dport)(dev_info_t *, sata_device_t *); int (*sata_tran_selftest)(dev_info_t *, sata_device_t *); /* Hotplug vector */ struct sata_tran_hotplug_ops *sata_tran_hotplug_ops; /* Power mgt vector */ struct sata_tran_pwrmgt_ops *sata_tran_pwrmgt_ops; int (*sata_tran_ioctl)(dev_info_t *, int, intptr_t); }; typedef struct sata_hba_tran sata_hba_tran_t; /* * Controller's features support flags (sata_tran_hba_features_support). * Note: SATA_CTLF_NCQ indicates that SATA controller supports NCQ in addition * to legacy queuing commands, indicated by SATA_CTLF_QCMD flag. */ #define SATA_CTLF_ATAPI 0x001 /* ATAPI support */ #define SATA_CTLF_PORT_MULTIPLIER 0x010 /* Port Multiplier suport */ #define SATA_CTLF_HOTPLUG 0x020 /* Hotplug support */ #define SATA_CTLF_ASN 0x040 /* Asynchronous Event Support */ #define SATA_CTLF_QCMD 0x080 /* Queued commands support */ #define SATA_CTLF_NCQ 0x100 /* NCQ support */ #define SATA_CTLF_PMULT_FBS 0x200 /* FIS-based switching support */ /* * sata_tran_start() return values. * When pkt is not accepted, the satapkt_reason has to be updated * before function returns - it should reflect the same reason for not being * executed as the return status of above functions. * If pkt was accepted and executed synchronously, * satapk_reason should indicate a completion status. */ #define SATA_TRAN_ACCEPTED 0 /* accepted */ #define SATA_TRAN_QUEUE_FULL 1 /* not accepted, queue full */ #define SATA_TRAN_PORT_ERROR 2 /* not accepted, port error */ #define SATA_TRAN_CMD_UNSUPPORTED 3 /* not accepted, cmd not supported */ #define SATA_TRAN_BUSY 4 /* not accepted, busy */ /* * sata_tran_abort() abort type flag */ #define SATA_ABORT_PACKET 0 #define SATA_ABORT_ALL_PACKETS 1 /* * Events handled by SATA HBA Framework * More then one event may be reported at the same time * * SATA_EVNT__DEVICE_ATTACHED * HBA detected the presence of a device ( electrical connection with * a device was detected ). * * SATA_EVNT_DEVICE_DETACHED * HBA detected the detachment of a device (electrical connection with * a device was broken) * * SATA_EVNT_LINK_LOST * HBA lost link with an attached device * * SATA_EVNT_LINK_ESTABLISHED * HBA established a link with an attached device * * SATA_EVNT_PORT_FAILED * HBA has determined that the port failed and is unuseable * * SATA_EVENT_DEVICE_RESET * SATA device was reset, causing loss of the device setting * * SATA_EVNT_PWR_LEVEL_CHANGED * A port or entire SATA controller power level has changed * * SATA_EVNT_PMULT_LINK_CHANGED * Port multiplier detect change on a link of its device port * */ #define SATA_EVNT_DEVICE_ATTACHED 0x01 #define SATA_EVNT_DEVICE_DETACHED 0x02 #define SATA_EVNT_LINK_LOST 0x04 #define SATA_EVNT_LINK_ESTABLISHED 0x08 #define SATA_EVNT_PORT_FAILED 0x10 #define SATA_EVNT_DEVICE_RESET 0x20 #define SATA_EVNT_PWR_LEVEL_CHANGED 0x40 #define SATA_EVNT_PMULT_LINK_CHANGED 0x80 /* * SATA Framework interface entry points */ int sata_hba_init(struct modlinkage *); int sata_hba_attach(dev_info_t *, sata_hba_tran_t *, ddi_attach_cmd_t); int sata_hba_detach(dev_info_t *, ddi_detach_cmd_t); void sata_hba_fini(struct modlinkage *); void sata_hba_event_notify(dev_info_t *, sata_device_t *, int); sata_pkt_t *sata_get_error_retrieval_pkt(dev_info_t *, sata_device_t *, int); void sata_free_error_retrieval_pkt(sata_pkt_t *); sata_pkt_t *sata_get_rdwr_pmult_pkt(dev_info_t *, sata_device_t *, uint16_t, uint32_t, uint32_t); void sata_free_rdwr_pmult_pkt(sata_pkt_t *); void sata_register_pmult(dev_info_t *, sata_device_t *, sata_pmult_gscr_t *); void sata_free_dma_resources(sata_pkt_t *); void sata_split_model(char *, char **, char **); /* * SATA trace ring buffer constants */ #define DMSG_RING_SIZE 0x100000 /* 1MB */ #define DMSG_BUF_SIZE 256 /* * SATA trace ring buffer content */ typedef struct sata_trace_dmsg { dev_info_t *dip; timespec_t timestamp; char buf[DMSG_BUF_SIZE]; struct sata_trace_dmsg *next; } sata_trace_dmsg_t; /* * SATA trace ring buffer header */ typedef struct sata_trace_rbuf { kmutex_t lock; /* lock to avoid clutter */ int looped; /* completed ring */ int allocfailed; /* dmsg mem alloc failed */ size_t size; /* current size */ size_t maxsize; /* max size */ sata_trace_dmsg_t *dmsgh; /* messages head */ sata_trace_dmsg_t *dmsgp; /* ptr to last message */ } sata_trace_rbuf_t; /* * SATA trace ring buffer interfaces */ void sata_trace_debug(dev_info_t *, const char *fmt, ...); void sata_vtrace_debug(dev_info_t *, const char *fmt, va_list); #ifdef __cplusplus } #endif #endif /* _SATA_HBA_H */