I am sponsoring the resubmission of this case. The timer expires on 9/24/2009.
This fast-track was approved back in July. However, after the associated code changes were integrated into Nevada, some issues were discovered and the sata team decided to rework the case. Here are the changes relative to the case that was approved in July: 1. Eliminate a change to the sata framework's existing sata_device structure. 2. Add a definition for an additional port multiplier "qualifier". 3. Add a field to one of the new data structure for future expansion. 4. Rename the function sata_check_pmult_blacklist to sata_register_pmult and use it in a somewhat different manner than in the original case. 1. Introduction =============== 1.1. Project/Component Working Name: SATA Framework Port Multiplier Support 1.2. Name of Document Author/Supplier: Author: Xiao-Yu Zhang 1.3. Date of This Document: 9/17/2009 4. Technical Description ======================== 4.1. Background --------------- PSARC/2004/779 [1] established the SATA HBA Framework interface. PSARC/2005/679 [2] expanded this interface as needed to support the marvell88sx and si3124 SATA HBA drivers. PSARC 2007/274 [3] expanded the interface further to support Native Command Queuing (NCQ) and ATAPI devices. PSARC/2007/448 [4] expanded the interface again to support releasing DMA framework-allocated resources associated with a command's buffer. This fast-track describes further interface changes required to support SATA port multipliers. 4.2. The Problem ---------------- 4.2.1. Required to support READ/WRITE PORTMULT command ------------------------------------------------------ According to the SATA Specification 2.6 [5] and the Port Multiplier Specification [6], READ PORT MULTIPLIER and WRITE PORT MULTIPLIER are used to access the registers of the port multiplier. These two commands are necessary to the successful enumeration of the the port multiplier. Both SATA HBA drivers as well as the SATA module have internal functions operating on sata_pkt rather than isolated SATA commands. Therefore, READ/WRITE PORTMULT commands should be delivered to SATA HBA drivers in sata_pkt structures. 4.2.2. Required to retrieve port multiplier information ------------------------------------------------------- Existing HBA implementations update only SATA Control Registers values in response to probe port operation. The port multiplier has its own Global Status & Control Registers, in which the parameters and status of the port multiplier itself are stored. The sata module needs the register information, so there needs to be a method for the SATA HBA driver to transfer the GSCR information to the sata module. 4.2.3. Required to handle port multiplier quirks ------------------------------------------------ The SATA specification 2.6 [5] defines the registers and enumeration process for port multipliers, however, some existing port multiplier models have quirks and might break the general enumeration or initialization process. The HBA driver should have idea of these quirks and determine its reaction. Additions to the interface are required to handle Port Multiplier behavior that is different from the specification. 4.3. The Proposal ----------------- 4.3.1. Summary -------------- Revise the SATA interface to support port multiplier. Port multiplier support was partially designed and implemented inside SATA module. The proposal defines new interface functions necessary to support new SATA commands. A new structure is defined to store GSCR register of the port multiplier device and a new interface function for the HBA driver to transfer the GSCR information to sata module and retrieve the necessary information of the port multiplier discrepancies from the SATA specification. The initial consumer of the modified interface will be AHCI driver implementing SATA port multiplier support. Since the existing SATA HBA drivers and SATA module do not currently implement the structure version checking (except for sata_hba_tran structure), the proposed change will maintain the binary compatibility. A SATA module supporting these interface changes will operate with SATA HBA drivers using the unmodified interface as well as SATA HBA drivers using the modified interface. 4.3.2. Interface Modifications ------------------------------ a) Add a new structure sata_pmult_gscr. (See section 5.2.1 for more details) b) Add a new qualifier SATA_ADDR_PMULT_SPEC (See section 5.3.1 for more details). c) The sata_hba_tran structure version (SATA_TRAN_HBA_REV) will be increased to 3 to indicate new functionality level of the entire SATA framework interface. (See section 5.3.2 for more details) d) Add three new SATA module interface functions. + sata_get_rdwr_pmult_pkt(); + sata_free_rdwr_pmult_pkt(); + sata_register_pmult(); (See section 5.4 for more details) 4.5. Stability level -------------------- The stability level of the new interfaces will be the same as the other interfaces between SATA HBA Framework (SATA module) and SATA HBA driver, i.e. Consolidation Private. The requested release binding is micro release and patch release. 5. Interface Table ================== 5.1. Exported Interfaces ------------------------ ------------------------------------------------------------------------ Interface Level Comments ------------------------------------------------------------------------ SATA_TRAN_HBA_REV Consolidation Symbol Private (redefine) SATA_TRAN_HBA_REV_3 Consolidation sata_hba_tran version Private (new) SATA_ADDR_PMULT_SPEC Consolidation Symbol Private (new) sata_pmult_gscr Consolidation Interface structure Private (new) sata_get_rdwr_pmult_pkt Consolidation Interface function Private (new) sata_free_rdwr_pmult_pkt Consolidation Interface function Private (new) sata_register_pmult Consolidation Interface function Private (new) 5.2. New structures ------------------- 5.2.1. New structure: sata_pmult_gscr ------------------------------------- struct sata_pmult_gscr { uint32_t gscr0; /* Product Identifier register */ uint32_t gscr1; /* Reserved Information register */ uint32_t gscr2; /* Port Information register */ uint32_t gscr64; /* Feature register */ uint32_t resv[4]; /* Reserved */ }; Implementation Notes: The structure sata_pmult_gscr stores the GSCR registers of the port multiplier. The reserved field is for expandability in the future. 5.3. Symbols ------------ 5.3.1. New symbol: SATA_ADDR_PMULT_SPEC --------------------------------------- The modified field is indicated by a change bar. New definition: #define SATA_ADDR_CNTRL 0x10 /* Controller */ #define SATA_ADDR_PMULT 0x20 /* Port Multiplier */ |#define SATA_ADDR_PMULT_SPEC 0x40 /* Port Multiplier Specific */ Implementation Notes: The address qualifier SATA_ADDR_PMULT_SPEC specifies the global registers of the port multiplier. The SATA Framework first probes a controller port with SATA_ADDR_CPORT address qualifier. If the returned device type is a port multiplier, the SATA Framework performs an additional port probe with the SATA_ADDR_PMULT_SPEC address qualifier to request that the HBA driver register the port multiplier with the SATA Framework by calling the sata_register_pmult function. The new qualifier does not affect the SATA HBA drivers which returns unknown device when a port multiplier is attached. For the other HBA drivers with older version of the interface, the sata_tran_probe_port function may return port multiplier device type. But when sata module performs the additional probe specifying SATA_ADDR_PMULT_SPEC, the sata_tran_probe_port function ignores the new qualifier and just probes the controller port again. The sata_register_pmult function is not called and SATA_DSTATE_PMULT_INIT is not properly set. Hence the sata module will set the port multiplier as failed. 5.3.2. SATA_TRAN_HBA_REV redefinition ------------------------------------- Modified field is indicated by a change bar. Old definition: |#define SATA_TRAN_HBA_REV SATA_TRAN_HBA_REV_2 New definitions: |#define SATA_TRAN_HBA_REV_3 3 |#define SATA_TRAN_HBA_REV SATA_TRAN_HBA_REV_3 Only version level of the sata_hba_tran structure is modified to indicate new functionality level of the entire SATA framework interface. New functionality includes: a) SATA module functions to get and free READ/WRITE PORTMULT sata packets. b) SATA port multiplier blacklist in SATA module c) SATA module functions to enable SATA HBA drivers to register port multiplier with SATA Framework 5.4. New Interface Functions ---------------------------- 5.4.1. sata_get_rdwr_pmult_pkt ------------------------------ #define SATA_RDWR_PMULT_PKT_TYPE_READ 1 #define SATA_RDWR_PMULT_PKT_TYPE_WRITE 2 NAME sata_get_rdwr_pmult_pkt - get sata packet to execute READ/WRITE PORTMULT command SYNOPSIS #include <sys/sata/impl/sata_hba.h> sata_pkt_t *sata_get_rdwr_pmult_pkt(dev_info_t *dip, sata_device_t *sata_device, uint8_t regn, uint32_t regv, uint32_t type); INTERFACE LEVEL Consolidation Private PARAMETERS dip Pointer to a dev_info_t structure, referring to the HBA device instance. sata_device Pointer to the structure specifying the SATA device address. regn Register that is supposed to be read/write. regv The value of the target register. This parameter is only used when the type parameter is set to SATA_RDWR_PMULT_PKT_TYPE_WRITE. type SATA_RDWR_PMULT_PKT_TYPE_READ Returned sata_pkt structure should contain READ PORTMULT command. SATA_RDWR_PMULT_PKT_TYPE_WRITE Returned sata_pkt structure should contain WRITE PORTMULT command. DESCRIPTION The sata_get_rdwr_pmult_pkt function is called by SATA HBA driver to obtain a fully initialized sata_pkt containing a READ/WRITE PORTMULT command, as well as a DMA-capable data buffer and DMA resources for the data buffer. The data buffer will satisfy HBA DMA attributes restrictions. The same data buffer could be also used for programmed I/O. The target register is specified by the regn argument. The command type is specified by type argument. The initialized sata packet does not specify any completion callback routine. No packet completion reason nor packet status is to be returned to SATA module. Once the SATA HBA completes sata_pkt usage, it should call sata_free_rdwr_pmult_pkt() function to free the packet and allocated resources. RETURN VALUES Returns a pointer to initialized sata_pkt if the function succeeds, and returns Null, if packet could not be allocated and/or initialized. CONTEXT This function cannot be called from the interrupt context. 5.4.2. sata_free_rdwr_pmult_pkt ------------------------------- NAME sata_free_rdwr_pmult_pkt - free sata packet allocated for READ/WRITE PORTMULT command SYNOPSIS #include <sys/sata/impl/sata_hba.h> void sata_free_rdwr_pmult_pkt(sata_pkt_t *sata_pkt); INTERFACE LEVEL Consolidation Private PARAMETERS sata_pkt sata_pkt allocated previously by the sata_get_rdwr_pmult_pkt(). DESCRIPTION sata_free_rdwr_pmult_pkt function is called by the SATA HBA driver in order to release the sata_pkt structure allocated previously by sata_get_rdwr_pmult_pkt(). All resources associated with the packet are freed. After calling this function, the SATA HBA driver should not attempt to access any field and/or data buffer associated with the freed sata_pkt. RETURN VALUES Void CONTEXT This function may be called from the interrupt context. 5.4.3. sata_register_pmult -------------------------- NAME sata_register_pmult - register a port multiplier with the SATA Framework SYNOPSIS #include <sys/sata/impl/sata_hba.h> void sata_register_pmult(dev_info_t *dev_info, sata_device_t *sata_device, sata_pmult_gscr_t *sata_gscr); INTERFACE LEVEL Consolidation Private PARAMETERS dev_info Pointer to a dev_info_t structure, referring to the HBA device instance. sata_device Pointer to a sata_device structure that contains the address of the port multiplier. sata_gscr Pointer to a sata_pmult_gscr structure that contains the global status and control register values of a port multiplier. DESCRIPTION The sata_register_pmult function is called by the SATA HBA driver to register a port multiplier with the SATA Framework. It is only called in response to sata_tran_probe_port call when the address qualifier is set to SATA_ADDR_PMULT_SPEC. During initial device enumeration and in case the device status is changed, the SATA Framework probes a controller port specifying SATA_ADDR_CPORT. If the device type returned by the HBA driver is port multiplier the SATA Framework then probes the controller port again with qualifier SATA_ADDR_PMULT_SPEC. In that case the HBA should read the GSCRs of the port multiplier and register the port multiplier via sata_register_pmult which stores the GSCR informations of the port multiplier. The number of the device ports is returned in the sata_device.satadev_add_info. RETURN VALUES void CONTEXT This function may be called from the interrupt context. 6. Release Summary ================== S11, S10 Update 7. Packaging Changes ==================== 7.1. Binaries Modified ---------------------- /kernel/misc/sata /kernel/misc/amd64/sata /usr/include/sys/sata/sata_hba.h /kernel/drv/ahci /kernel/drv/amd64/ahci 7.2. Packages Affected ---------------------- SUNWckr SUNWhea SUNWahci 8. References ============= [1] PSARC/2004/779 - SATA Framework Support [2] PSARC/2005/679 - SATA Framework Support (Updated) [3] PSARC/2007/274 - SATA Framework Interface Revision [4] PSARC/2008/448 - SATA Framework Addition [5] SATA Specification 2.6, Serial ATA International Organization [6] SATA Port Multiplier Specification 1.2, Serial ATA International Organization 9. Steering Committee requested information =========================================== 9.1. Consolidation C-team Name: ON 9.2. ARC review type: FastTrack