Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
15.  SCSI Host Bus Adapter Drivers HBA Driver Dependency and Configuration Issues Autoconfiguration Entry Points attach() Entry Point (SCSI HBA Drivers)  Previous   Contents   Next 
   
 

Soft State Structure

The driver should allocate the per-device-instance soft state structure, being careful to clean up properly if an error occurs.

DMA

The HBA driver must describe the attributes of its DMA engine by properly initializing the ddi_dma_attr_t structure.

static ddi_dma_attr_t isp_dma_attr = {
         DMA_ATTR_V0,        /* ddi_dma_attr version */
         0,                  /* low address */
         0xffffffff,         /* high address */
         0x00ffffff,         /* counter upper bound */
         1,                  /* alignment requirements */
         0x3f,               /* burst sizes */
         1,                  /* minimum DMA access */
         0xffffffff,         /* maximum DMA access */
         (1<<24)-1,          /* segment boundary restrictions */
         1,                  /* scatter/gather list length */
         512,                /* device granularity */
         0                   /* DMA flags */
};

The driver, if providing DMA, should also check that its hardware is installed in a DMA-capable slot:

        if (ddi_slaveonly(dip) == DDI_SUCCESS) {
             return (DDI_FAILURE);
         }

Transport Structure

The driver should further allocate and initialize a transport structure for this instance. The tran_hba_private field is set to point to this instance's soft-state structure. tran_tgt_probe can be set to NULL to achieve the default behavior, if no special probe customization is needed.

    tran = scsi_hba_tran_alloc(dip, SCSI_HBA_CANSLEEP);

     isp->isp_tran                   = tran;
     isp->isp_dip                    = dip;

     tran->tran_hba_private          = isp;
     tran->tran_tgt_private          = NULL;
     tran->tran_tgt_init             = isp_tran_tgt_init;
     tran->tran_tgt_probe            = scsi_hba_probe;
     tran->tran_tgt_free             = (void (*)())NULL;

     tran->tran_start                = isp_scsi_start;
     tran->tran_abort                = isp_scsi_abort;
     tran->tran_reset                = isp_scsi_reset;
     tran->tran_getcap               = isp_scsi_getcap;
     tran->tran_setcap               = isp_scsi_setcap;
     tran->tran_init_pkt             = isp_scsi_init_pkt;
     tran->tran_destroy_pkt          = isp_scsi_destroy_pkt;
     tran->tran_dmafree              = isp_scsi_dmafree;
     tran->tran_sync_pkt             = isp_scsi_sync_pkt;
     tran->tran_reset_notify         = isp_scsi_reset_notify;
     tran->tran_bus_quiesce          = isp_tran_bus_quiesce
     tran->tran_bus_unquiesce        = isp_tran_bus_unquiesce
     tran->tran_bus_reset            = isp_tran_bus_reset

Attaching an HBA Driver

The driver should attach this instance of the device, and perform error cleanup if necessary.

    i = scsi_hba_attach_setup(dip, &isp_dma_attr, tran, 0);
    if (i != DDI_SUCCESS) {
         do error recovery     
            return (DDI_FAILURE);
     }

Register Mapping

The driver should map in its device's registers, specifying the index of the register set, the data access characteristics of the device and the size of the register set to be mapped.

ddi_device_acc_attr_t                        dev_attributes;

     dev_attributes.devacc_attr_version = DDI_DEVICE_ATTR_V0;
     dev_attributes.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
     dev_attributes.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;

     if (ddi_regs_map_setup(dip, 0, (caddr_t *)&isp->isp_reg,
         0, sizeof (struct ispregs), &dev_attributes,
         &isp->isp_acc_handle) != DDI_SUCCESS) {
         do error recovery
            return (DDI_FAILURE);
     }

Adding an Interrupt Handler

The driver must first obtain the iblock cookie to initialize mutexes used in the driver handler. Only after those mutexes have been initialized can the interrupt handler be added.

    i = ddi_get_iblock_cookie(dip, 0, &isp->iblock_cookie};
     if (i != DDI_SUCCESS) {
         do error recovery
            return (DDI_FAILURE);
     }

     mutex_init(&isp->mutex, "isp_mutex", MUTEX_DRIVER,
         (void *)isp->iblock_cookie);
     i = ddi_add_intr(dip, 0, &isp->iblock_cookie,
         0, isp_intr, (caddr_t)isp);
     if (i != DDI_SUCCESS) {
         do error recovery
            return (DDI_FAILURE);
     }

The driver should determine if a high-level interrupt handler is required. If a high-level handler is required and the driver is not coded to provide one, rewrite the driver to include either a high-level interrupt or fail the attach. See "Handling High-Level Interrupts" for a description of high-level interrupt handling.

Create Power Manageable Components

If the host bus adapter hardware supports power management, and the host bus adapter only needs to be powered down when all of the target adapters are power manageable and are at power level 0, then the host bus adapter driver only needs to provide a power(9E) entry point as described in Chapter 9, Power Management and create a pm-components(9P) property that describes the components that the device implements.

Nothing more is necessary, since the components will default to idle, and the power management framework's default dependency processing will ensure that the host bus adapter will be powered up whenever an target adapter is powered up and will automatically power down the host bus adapter whenever all of the target adapters are powered down (provided that automatic power management is enabled).

Report Attachment Status

Finally, the driver should report that this instance of the device is attached and return success.

    ddi_report_dev(dip);
     return (DDI_SUCCESS);

detach() Entry Point (SCSI HBA Drivers)

The driver should perform standard detach operations, including calling scsi_hba_detach(9F).

SCSA HBA Entry Points

For an HBA driver to work with target drivers using the SCSA interface, each HBA driver must supply a number of entry points, callable through the scsi_hba_tran(9S) structure.These entry points fall into five functional groups:

  • Target driver instance initialization

  • Resource allocation and deallocation

  • Command transport

  • Capability management

  • Abort and reset handling

  • Dynamic reconfiguration

 
 
 
  Previous   Contents   Next