ips.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:261k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1.                 (!ha->func.erasebios) ||
  2.                 (!ha->func.verifybios)) {
  3.                pt->BasicStatus = 0x0B;
  4.                pt->ExtendedStatus = 0x00;
  5.                SC->result = DID_ERROR << 16;
  6.                return (IPS_FAILURE);
  7.             }
  8.       /* must have a buffer */
  9.             if ((!pt->CmdBSize) || (!pt->CmdBuffer)) {
  10.                pt->BasicStatus = 0x0B;
  11.                pt->ExtendedStatus = 0x00;
  12.                SC->result = DID_ERROR << 16;
  13.          return (IPS_FAILURE);
  14.             }
  15.       /* make sure buffer is big enough */
  16.       if (pt->CmdBSize > ha->ioctl_datasize) {
  17.          void *bigger_struct;
  18.                u_int32_t count;
  19.                u_int32_t order;
  20.          /* try to allocate a bigger struct */
  21.                for (count = PAGE_SIZE, order = 0;
  22.                     count < pt->CmdBSize;
  23.                     order++, count <<= 1);
  24.                bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
  25.          if (bigger_struct) {
  26.             /* free the old memory */
  27.                   free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
  28.             /* use the new memory */
  29.                   ha->ioctl_data = (char *) bigger_struct;
  30.                   ha->ioctl_order = order;
  31.                   ha->ioctl_datasize = count;
  32.                } else {
  33.                   pt->BasicStatus = 0x0B;
  34.                   pt->ExtendedStatus = 0x00;
  35.                   SC->result = DID_ERROR << 16;
  36.                   spin_unlock(&ha->ips_lock);
  37.                   return (IPS_FAILURE);
  38.                }
  39.             }
  40.       /* copy in the buffer */
  41.       if (copy_from_user(ha->ioctl_data, pt->CmdBuffer, pt->CmdBSize) > 0) {
  42.          DEBUG_VAR(1, "(%s%d) flash bios failed - unable to copy user buffer",
  43.                    ips_name, ha->host_num);
  44.                pt->BasicStatus = 0x0B;
  45.                pt->ExtendedStatus = 0x00;
  46.                SC->result = DID_ERROR << 16;
  47.                return (EFAULT);
  48.             }
  49.             flash_data.userbuffer = pt->CmdBuffer;
  50.             flash_data.usersize = pt->CmdBSize;
  51.             flash_data.kernbuffer = ha->ioctl_data;
  52.             flash_data.kernsize = ha->ioctl_datasize;
  53.             flash_data.offset = le32_to_cpu(pt->CoppCP.cmd.flashbios.offset);
  54.             flash_data.SC = (void *) SC;
  55.             flash_data.pt = (void *) pt;
  56.             flash_data.ha = (void *) ha;
  57.             sema_init( &ha->flash_ioctl_sem, 0 );
  58.             flash_data.sem = &ha->flash_ioctl_sem;
  59.             task.sync = 0;
  60.             task.routine = ips_flash_bios_section;
  61.             task.data = (void *) &flash_data;
  62.             /* Unlock the master lock */
  63.             spin_unlock_irq(&io_request_lock);
  64.             queue_task(&task, &tq_immediate);
  65.             mark_bh(IMMEDIATE_BH);
  66.             
  67.             /* Wait for the flash to complete */
  68.             down(&ha->flash_ioctl_sem);
  69.             /* Obtain the master lock */
  70.             spin_lock_irq(&io_request_lock);
  71.             return (flash_data.retcode);
  72.          }
  73.          if ((pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW) &&
  74.              (pt->CoppCP.cmd.flashfw.type == 1) &&
  75.              (pt->CoppCP.cmd.flashfw.direction == 3) &&
  76.              (ha->device_id == IPS_DEVICEID_COPPERHEAD)) {
  77.             /* Erase the Card BIOS */
  78.             if (!ha->func.erasebios) {
  79.                pt->BasicStatus = 0x0B;
  80.                pt->ExtendedStatus = 0x00;
  81.                SC->result = DID_ERROR << 16;
  82.                return (IPS_FAILURE);
  83.             }
  84.       if ((*ha->func.erasebios)(ha)) {
  85.          DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
  86.                    ips_name, ha->host_num);
  87.                pt->BasicStatus = 0x0B;
  88.                pt->ExtendedStatus = 0x00;
  89.                SC->result = DID_ERROR << 16;
  90.                return (IPS_FAILURE);
  91.             }
  92.             SC->result = DID_OK << 16;
  93.             pt->BasicStatus = 0x00;
  94.             pt->ExtendedStatus = 0x00;
  95.             return (IPS_SUCCESS_IMM);
  96.          }
  97.          if (ips_newusrcmd(ha, pt, scb))
  98.             return (IPS_SUCCESS);
  99.          else
  100.             return (IPS_FAILURE);
  101.       }
  102.       break;
  103.    } /* end switch */
  104.          return (IPS_FAILURE);
  105.       }
  106. /****************************************************************************/
  107. /*                                                                          */
  108. /* Routine Name: ips_scheduled_flash_bios                                   */
  109. /*                                                                          */
  110. /* Routine Description:                                                     */
  111. /*                                                                          */
  112. /*   Flash the BIOS on a Copperhead style controller                        */
  113. /*   To be called from a task queue                                         */
  114. /*                                                                          */
  115. /****************************************************************************/
  116. static void
  117. ips_scheduled_flash_bios(void *data) {
  118.    ips_ha_t       *ha;
  119.    Scsi_Cmnd      *SC;
  120.    ips_passthru_t *pt;
  121.    IPS_FLASH_DATA *fd;
  122.    fd = (IPS_FLASH_DATA *) data;
  123.    ha = (ips_ha_t *) fd->ha;
  124.    pt = (ips_passthru_t *) fd->pt;
  125.    SC = (Scsi_Cmnd *) fd->SC;
  126.    /*
  127.     * Set initial return codes
  128.     */
  129.    SC->result = DID_OK << 16;
  130.    pt->BasicStatus = 0x00;
  131.    pt->ExtendedStatus = 0x00;
  132.    fd->retcode = IPS_SUCCESS_IMM;
  133.    /*
  134.     * Fix the size/ptr to account for the
  135.     * flash header
  136.     */
  137.    fd->kernbuffer += 0xC0;
  138.    fd->kernsize -= 0xC0;
  139.    fd->userbuffer += 0xC0;
  140.    fd->usersize -= 0xC0;
  141.    if ((*ha->func.erasebios)(ha)) {
  142.       DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
  143.                    ips_name, ha->host_num);
  144.       pt->BasicStatus = 0x0B;
  145.       pt->ExtendedStatus = 0x00;
  146.       SC->result = DID_ERROR << 16;
  147.       fd->retcode = IPS_FAILURE;
  148.       up(fd->sem);
  149.       return ;
  150.    }
  151.    ips_flash_bios_segment(data);
  152.    if (fd->retcode == IPS_FAILURE)
  153.       return ;
  154.    if ((*ha->func.verifybios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
  155.          DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
  156.                    ips_name, ha->host_num);
  157.       pt->BasicStatus = 0x0B;
  158.       pt->ExtendedStatus = 0x00;
  159.       SC->result = DID_ERROR << 16;
  160.       fd->retcode = IPS_FAILURE;
  161.       up(fd->sem);
  162.       return ;
  163.    }
  164.    /* Tell them we are done */
  165.    if (fd->retcode != IPS_FAILURE)
  166.       up(fd->sem);
  167. }
  168. /****************************************************************************/
  169. /*                                                                          */
  170. /* Routine Name: ips_flash_bios_section                                     */
  171. /*                                                                          */
  172. /* Routine Description:                                                     */
  173. /*                                                                          */
  174. /*   wrapper for ips_flash_bios_segment that raises the semaphore           */
  175. /*                                                                          */
  176. /****************************************************************************/
  177. static void
  178. ips_flash_bios_section(void *data) {
  179.    ips_ha_t       *ha;
  180.    Scsi_Cmnd      *SC;
  181.    ips_passthru_t *pt;
  182.    IPS_FLASH_DATA *fd;
  183.    fd = (IPS_FLASH_DATA *) data;
  184.    ha = (ips_ha_t *) fd->ha;
  185.    pt = (ips_passthru_t *) fd->pt;
  186.    SC = (Scsi_Cmnd *) fd->SC;
  187.    /*
  188.     * Set initial return codes
  189.     */
  190.    SC->result = DID_OK << 16;
  191.    pt->BasicStatus = 0x00;
  192.    pt->ExtendedStatus = 0x00;
  193.    fd->retcode = IPS_SUCCESS_IMM;
  194.    ips_flash_bios_segment(data);
  195.    if (fd->retcode != IPS_FAILURE)
  196.       up(fd->sem);
  197. }
  198. /****************************************************************************/
  199. /*                                                                          */
  200. /* Routine Name: ips_flash_bios_segment                                     */
  201. /*                                                                          */
  202. /* Routine Description:                                                     */
  203. /*                                                                          */
  204. /*   Flash a portion of the BIOS on a Copperhead style controller           */
  205. /*   To be called from a task queue                                         */
  206. /*                                                                          */
  207. /****************************************************************************/
  208. static void
  209. ips_flash_bios_segment(void *data) {
  210.    ips_ha_t       *ha;
  211.    Scsi_Cmnd      *SC;
  212.    ips_passthru_t *pt;
  213.    IPS_FLASH_DATA *fd;
  214.    fd = (IPS_FLASH_DATA *) data;
  215.    ha = (ips_ha_t *) fd->ha;
  216.    pt = (ips_passthru_t *) fd->pt;
  217.    SC = (Scsi_Cmnd *) fd->SC;
  218.    if ((*ha->func.programbios)(ha, fd->kernbuffer, fd->usersize, fd->offset)) {
  219.       DEBUG_VAR(1, "(%s%d) flash bios failed - unable to program flash",
  220.                 ips_name, ha->host_num);
  221.       pt->BasicStatus = 0x0B;
  222.       pt->ExtendedStatus = 0x00;
  223.       SC->result = DID_ERROR << 16;
  224.       fd->retcode = IPS_FAILURE;
  225.       up(fd->sem);
  226.       return ;
  227.    }
  228. }
  229. /****************************************************************************/
  230. /*                                                                          */
  231. /* Routine Name: ips_usrcmd                                                 */
  232. /*                                                                          */
  233. /* Routine Description:                                                     */
  234. /*                                                                          */
  235. /*   Process a user command and make it ready to send                       */
  236. /*                                                                          */
  237. /****************************************************************************/
  238. static int
  239. ips_usrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
  240.    IPS_SG_LIST *sg_list;
  241.    METHOD_TRACE("ips_usrcmd", 1);
  242.    if ((!scb) || (!pt) || (!ha))
  243.       return (0);
  244.    /* Save the S/G list pointer so it doesn't get clobbered */
  245.    sg_list = scb->sg_list;
  246.    /* copy in the CP */
  247.    memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
  248.    memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
  249.    /* FIX stuff that might be wrong */
  250.    scb->sg_list = sg_list;
  251.    scb->scb_busaddr = VIRT_TO_BUS(scb);
  252.    scb->bus = scb->scsi_cmd->channel;
  253.    scb->target_id = scb->scsi_cmd->target;
  254.    scb->lun = scb->scsi_cmd->lun;
  255.    scb->sg_len = 0;
  256.    scb->data_len = 0;
  257.    scb->flags = 0;
  258.    scb->op_code = 0;
  259.    scb->callback = ipsintr_done;
  260.    scb->timeout = ips_cmd_timeout;
  261.    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
  262.    /* we don't support DCDB/READ/WRITE Scatter Gather */
  263.    if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
  264.        (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
  265.        (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
  266.       return (0);
  267.    if (pt->CmdBSize) {
  268.       scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
  269.    } else {
  270.       scb->data_busaddr = 0L;
  271.    }
  272.    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
  273.       scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
  274.    if (pt->CmdBSize) {
  275.       if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
  276.          scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
  277.       else
  278.          scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
  279.    }
  280.    /* set timeouts */
  281.    if (pt->TimeOut) {
  282.       scb->timeout = pt->TimeOut;
  283.       if (pt->TimeOut <= 10)
  284.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
  285.       else if (pt->TimeOut <= 60)
  286.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
  287.       else
  288.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
  289.    }
  290.    /* assume success */
  291.    scb->scsi_cmd->result = DID_OK << 16;
  292.    /* success */
  293.    return (1);
  294. }
  295. /****************************************************************************/
  296. /*                                                                          */
  297. /* Routine Name: ips_newusrcmd                                              */
  298. /*                                                                          */
  299. /* Routine Description:                                                     */
  300. /*                                                                          */
  301. /*   Process a user command and make it ready to send                       */
  302. /*                                                                          */
  303. /****************************************************************************/
  304. static int
  305. ips_newusrcmd(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb) {
  306.    IPS_SG_LIST    *sg_list;
  307.    char           *user_area;
  308.    char           *kern_area;
  309.    u_int32_t       datasize;
  310.    METHOD_TRACE("ips_usrcmd", 1);
  311.    if ((!scb) || (!pt) || (!ha))
  312.       return (0);
  313.    /* Save the S/G list pointer so it doesn't get clobbered */
  314.    sg_list = scb->sg_list;
  315.    /* copy in the CP */
  316.    memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
  317.    memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof(IPS_DCDB_TABLE));
  318.    /* FIX stuff that might be wrong */
  319.    scb->sg_list = sg_list;
  320.    scb->scb_busaddr = VIRT_TO_BUS(scb);
  321.    scb->bus = scb->scsi_cmd->channel;
  322.    scb->target_id = scb->scsi_cmd->target;
  323.    scb->lun = scb->scsi_cmd->lun;
  324.    scb->sg_len = 0;
  325.    scb->data_len = 0;
  326.    scb->flags = 0;
  327.    scb->op_code = 0;
  328.    scb->callback = ipsintr_done;
  329.    scb->timeout = ips_cmd_timeout;
  330.    scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
  331.    /* we don't support DCDB/READ/WRITE Scatter Gather */
  332.    if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
  333.        (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
  334.        (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
  335.       return (0);
  336.    if (pt->CmdBSize) {
  337.       if (pt->CmdBSize > ha->ioctl_datasize) {
  338.          void *bigger_struct;
  339.          u_int32_t count;
  340.          u_int32_t order;
  341.          /* try to allocate a bigger struct */
  342.          for (count = PAGE_SIZE, order = 0;
  343.               count < pt->CmdBSize;
  344.               order++, count <<= 1);
  345.          bigger_struct = (void *) __get_free_pages(GFP_ATOMIC, order);
  346.          if (bigger_struct) {
  347.             /* free the old memory */
  348.             free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
  349.             /* use the new memory */
  350.             ha->ioctl_data = (char *) bigger_struct;
  351.             ha->ioctl_order = order;
  352.             ha->ioctl_datasize = count;
  353.          } else
  354.             return (0);
  355.       }
  356.       scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data);
  357.       /* Attempt to copy in the data */
  358.       user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
  359.       kern_area = ha->ioctl_data;
  360.       datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
  361.       if (copy_from_user(kern_area, user_area, datasize) > 0) {
  362.          DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
  363.                    ips_name, ha->host_num);
  364.          return (0);
  365.       }
  366.    } else {
  367.       scb->data_busaddr = 0L;
  368.    }
  369.    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
  370.       scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
  371.    if (pt->CmdBSize) {
  372.       if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
  373.          scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
  374.       else
  375.          scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
  376.    }
  377.    /* set timeouts */
  378.    if (pt->TimeOut) {
  379.       scb->timeout = pt->TimeOut;
  380.       if (pt->TimeOut <= 10)
  381.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
  382.       else if (pt->TimeOut <= 60)
  383.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
  384.       else
  385.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
  386.    }
  387.    /* assume success */
  388.    scb->scsi_cmd->result = DID_OK << 16;
  389.    /* success */
  390.    return (1);
  391. }
  392. /****************************************************************************/
  393. /*                                                                          */
  394. /* Routine Name: ips_cleanup_passthru                                       */
  395. /*                                                                          */
  396. /* Routine Description:                                                     */
  397. /*                                                                          */
  398. /*   Cleanup after a passthru command                                       */
  399. /*                                                                          */
  400. /****************************************************************************/
  401. static void
  402. ips_cleanup_passthru(ips_ha_t *ha, ips_scb_t *scb) {
  403.    ips_passthru_t *pt;
  404.    METHOD_TRACE("ips_cleanup_passthru", 1);
  405.    if ((!scb) || (!scb->scsi_cmd) || (!scb->scsi_cmd->request_buffer)) {
  406.       DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
  407.                 ips_name, ha->host_num);
  408.       return ;
  409.    }
  410.    pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
  411.    /* Copy data back to the user */
  412.    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)        /* Copy DCDB Back to Caller's Area */
  413.       memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof(IPS_DCDB_TABLE));
  414.    
  415.    pt->BasicStatus = scb->basic_status;
  416.    pt->ExtendedStatus = scb->extended_status;
  417.    if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) 
  418.       up(&ha->ioctl_sem);
  419.    
  420. }
  421. #endif
  422. /****************************************************************************/
  423. /*                                                                          */
  424. /* Routine Name: ips_host_info                                              */
  425. /*                                                                          */
  426. /* Routine Description:                                                     */
  427. /*                                                                          */
  428. /*   The passthru interface for the driver                                  */
  429. /*                                                                          */
  430. /****************************************************************************/
  431. static int
  432. ips_host_info(ips_ha_t *ha, char *ptr, off_t offset, int len) {
  433.    IPS_INFOSTR info;
  434.    METHOD_TRACE("ips_host_info", 1);
  435.    info.buffer = ptr;
  436.    info.length = len;
  437.    info.offset = offset;
  438.    info.pos = 0;
  439.    info.localpos = 0;
  440.    copy_info(&info, "nIBM ServeRAID General Information:nn");
  441.    if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
  442.        (le16_to_cpu(ha->nvram->adapter_type) != 0))
  443.       copy_info(&info, "tController Type                   : %sn", ips_adapter_name[ha->ad_type-1]);
  444.    else
  445.       copy_info(&info, "tController Type                   : Unknownn");
  446.    if (ha->io_addr)
  447.       copy_info(&info, "tIO region                         : 0x%lx (%d bytes)n",
  448.                 ha->io_addr, ha->io_len);
  449.    if (ha->mem_addr) {
  450.       copy_info(&info, "tMemory region                     : 0x%lx (%d bytes)n",
  451.                 ha->mem_addr, ha->mem_len);
  452.       copy_info(&info, "tShared memory address             : 0x%lxn", ha->mem_ptr);
  453.    }
  454.    copy_info(&info, "tIRQ number                        : %dn", ha->irq);
  455.    if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG)
  456.       copy_info(&info, "tBIOS Version                      : %c%c%c%c%c%c%c%cn",
  457.                 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
  458.                 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
  459.                 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
  460.                 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
  461.    copy_info(&info, "tFirmware Version                  : %c%c%c%c%c%c%c%cn",
  462.              ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
  463.              ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
  464.              ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
  465.              ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
  466.    copy_info(&info, "tBoot Block Version                : %c%c%c%c%c%c%c%cn",
  467.              ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
  468.              ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
  469.              ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
  470.              ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
  471.    copy_info(&info, "tDriver Version                    : %s%sn",
  472.              IPS_VERSION_HIGH, IPS_VERSION_LOW);
  473.    copy_info(&info, "tMax Physical Devices              : %dn",
  474.              ha->enq->ucMaxPhysicalDevices);
  475.    copy_info(&info, "tMax Active Commands               : %dn",
  476.              ha->max_cmds);
  477.    copy_info(&info, "tCurrent Queued Commands           : %dn",
  478.              ha->scb_waitlist.count);
  479.    copy_info(&info, "tCurrent Active Commands           : %dn",
  480.              ha->scb_activelist.count - ha->num_ioctl);
  481.    copy_info(&info, "tCurrent Queued PT Commands        : %dn",
  482.              ha->copp_waitlist.count);
  483.    copy_info(&info, "tCurrent Active PT Commands        : %dn",
  484.              ha->num_ioctl);
  485.    copy_info(&info, "n");
  486.    return (info.localpos);
  487. }
  488. /****************************************************************************/
  489. /*                                                                          */
  490. /* Routine Name: copy_mem_info                                              */
  491. /*                                                                          */
  492. /* Routine Description:                                                     */
  493. /*                                                                          */
  494. /*   Copy data into an IPS_INFOSTR structure                                */
  495. /*                                                                          */
  496. /****************************************************************************/
  497. static void
  498. copy_mem_info(IPS_INFOSTR *info, char *data, int len) {
  499.    METHOD_TRACE("copy_mem_info", 1);
  500.    if (info->pos + len < info->offset) {
  501.       info->pos += len;
  502.       return;
  503.    }
  504.    if (info->pos < info->offset) {
  505.       data += (info->offset - info->pos);
  506.       len -= (info->offset - info->pos);
  507.       info->pos += (info->offset - info->pos);
  508.    }
  509.    if (info->localpos + len > info->length)
  510.       len = info->length - info->localpos;
  511.    if (len > 0) {
  512.       memcpy(info->buffer + info->localpos, data, len);
  513.       info->pos += len;
  514.       info->localpos += len;
  515.    }
  516. }
  517. /****************************************************************************/
  518. /*                                                                          */
  519. /* Routine Name: copy_info                                                  */
  520. /*                                                                          */
  521. /* Routine Description:                                                     */
  522. /*                                                                          */
  523. /*   printf style wrapper for an info structure                             */
  524. /*                                                                          */
  525. /****************************************************************************/
  526. static int
  527. copy_info(IPS_INFOSTR *info, char *fmt, ...) {
  528.    va_list args;
  529.    char buf[128];
  530.    int len;
  531.    METHOD_TRACE("copy_info", 1);
  532.    va_start(args, fmt);
  533.    len = vsprintf(buf, fmt, args);
  534.    va_end(args);
  535.    copy_mem_info(info, buf, len);
  536.    return (len);
  537. }
  538. /****************************************************************************/
  539. /*                                                                          */
  540. /* Routine Name: ips_identify_controller                                    */
  541. /*                                                                          */
  542. /* Routine Description:                                                     */
  543. /*                                                                          */
  544. /*   Identify this controller                                               */
  545. /*                                                                          */
  546. /****************************************************************************/
  547. static void
  548. ips_identify_controller(ips_ha_t *ha) {
  549.    METHOD_TRACE("ips_identify_controller", 1);
  550.    switch (ha->device_id) {
  551.    case IPS_DEVICEID_COPPERHEAD:
  552.       if (ha->revision_id <= IPS_REVID_SERVERAID) {
  553.          ha->ad_type = IPS_ADTYPE_SERVERAID;
  554.       } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
  555.          ha->ad_type = IPS_ADTYPE_SERVERAID2;
  556.       } else if (ha->revision_id == IPS_REVID_NAVAJO) {
  557.          ha->ad_type = IPS_ADTYPE_NAVAJO;
  558.       } else if ((ha->revision_id == IPS_REVID_SERVERAID2) && (ha->slot_num == 0)) {
  559.          ha->ad_type = IPS_ADTYPE_KIOWA;
  560.       } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
  561.                  (ha->revision_id <= IPS_REVID_CLARINETP3)) {
  562.          if (ha->enq->ucMaxPhysicalDevices == 15)
  563.             ha->ad_type = IPS_ADTYPE_SERVERAID3L;
  564.          else
  565.             ha->ad_type = IPS_ADTYPE_SERVERAID3;
  566.       } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
  567.                  (ha->revision_id <= IPS_REVID_TROMBONE64)) {
  568.          ha->ad_type = IPS_ADTYPE_SERVERAID4H;
  569.       }
  570.       break;
  571.    case IPS_DEVICEID_MORPHEUS:
  572.       switch (ha->subdevice_id) {
  573.       case IPS_SUBDEVICEID_4L:
  574.          ha->ad_type = IPS_ADTYPE_SERVERAID4L;
  575.          break;
  576.       case IPS_SUBDEVICEID_4M:
  577.          ha->ad_type = IPS_ADTYPE_SERVERAID4M;
  578.          break;
  579.       case IPS_SUBDEVICEID_4MX:
  580.          ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
  581.          break;
  582.       case IPS_SUBDEVICEID_4LX:
  583.          ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
  584.          break;
  585.       }
  586.       break;
  587.    }
  588. }
  589. /****************************************************************************/
  590. /*                                                                          */
  591. /* Routine Name: ips_create_nvrampage5                                      */
  592. /*                                                                          */
  593. /* Routine Description:                                                     */
  594. /*                                                                          */
  595. /*   Create a pseudo nvram page 5                                           */
  596. /*                                                                          */
  597. /****************************************************************************/
  598. static void
  599. ips_create_nvrampage5(ips_ha_t *ha, IPS_NVRAM_P5 *nvram) {
  600.    METHOD_TRACE("ips_create_nvrampage5", 1);
  601.    memset(nvram, 0, sizeof(IPS_NVRAM_P5));
  602.    nvram->signature = IPS_NVRAM_P5_SIG;
  603.    nvram->adapter_slot = ha->slot_num;
  604.    nvram->adapter_type = ha->ad_type;
  605.    nvram->operating_system = IPS_OS_LINUX;
  606.    strncpy((char *) nvram->driver_high, IPS_VERSION_HIGH, 4);
  607.    strncpy((char *) nvram->driver_low, IPS_VERSION_LOW, 4);
  608.    strncpy((char *) nvram->bios_high, ha->bios_version, 4);
  609.    strncpy((char *) nvram->bios_low, ha->bios_version + 4, 4);
  610. }
  611. /****************************************************************************/
  612. /*                                                                          */
  613. /* Routine Name: ips_get_bios_version                                       */
  614. /*                                                                          */
  615. /* Routine Description:                                                     */
  616. /*                                                                          */
  617. /*   Get the BIOS revision number                                           */
  618. /*                                                                          */
  619. /****************************************************************************/
  620. static void
  621. ips_get_bios_version(ips_ha_t *ha, int intr) {
  622.    ips_scb_t *scb;
  623.    int        ret;
  624.    u_int8_t   major;
  625.    u_int8_t   minor;
  626.    u_int8_t   subminor;
  627.    u_int8_t  *buffer;
  628.    char       hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  629.    METHOD_TRACE("ips_get_bios_version", 1);
  630.    major = 0;
  631.    minor = 0;
  632.    strncpy(ha->bios_version, "       ?", 8);
  633.    if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
  634.       if (IPS_USE_MEMIO(ha)) {
  635.          /* Memory Mapped I/O */
  636.          /* test 1st byte */
  637.          writel(0, ha->mem_ptr + IPS_REG_FLAP);
  638.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  639.             udelay(5); /* 5 us */
  640.          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
  641.             return;
  642.          writel(cpu_to_le32(1), ha->mem_ptr + IPS_REG_FLAP);
  643.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  644.             udelay(5); /* 5 us */
  645.          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
  646.             return;
  647.          /* Get Major version */
  648.          writel(cpu_to_le32(0x1FF), ha->mem_ptr + IPS_REG_FLAP);
  649.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  650.             udelay(5); /* 5 us */
  651.          major = readb(ha->mem_ptr + IPS_REG_FLDP);
  652.          /* Get Minor version */
  653.          writel(cpu_to_le32(0x1FE), ha->mem_ptr + IPS_REG_FLAP);
  654.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  655.             udelay(5); /* 5 us */
  656.          minor = readb(ha->mem_ptr + IPS_REG_FLDP);
  657.          /* Get SubMinor version */
  658.          writel(cpu_to_le32(0x1FD), ha->mem_ptr + IPS_REG_FLAP);
  659.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  660.             udelay(5); /* 5 us */
  661.          subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
  662.       } else {
  663.          /* Programmed I/O */
  664.          /* test 1st byte */
  665.          outl(0, ha->io_addr + IPS_REG_FLAP);
  666.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  667.             udelay(5); /* 5 us */
  668.          if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
  669.             return ;
  670.          outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
  671.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  672.             udelay(5); /* 5 us */
  673.          if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
  674.             return ;
  675.          /* Get Major version */
  676.          outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
  677.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  678.             udelay(5); /* 5 us */
  679.          major = inb(ha->io_addr + IPS_REG_FLDP);
  680.          /* Get Minor version */
  681.          outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
  682.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  683.             udelay(5); /* 5 us */
  684.          minor = inb(ha->io_addr + IPS_REG_FLDP);
  685.          /* Get SubMinor version */
  686.          outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
  687.          if (ha->revision_id == IPS_REVID_TROMBONE64)
  688.             udelay(5); /* 5 us */
  689.          subminor = inb(ha->io_addr + IPS_REG_FLDP);
  690.       }
  691.    } else {
  692.       /* Morpheus Family - Send Command to the card */
  693.       buffer = kmalloc(0x1000, GFP_ATOMIC);
  694.       if (!buffer)
  695.          return;
  696.       memset(buffer, 0, 0x1000);
  697.       scb = &ha->scbs[ha->max_cmds-1];
  698.       ips_init_scb(ha, scb);
  699.       scb->timeout = ips_cmd_timeout;
  700.       scb->cdb[0] = IPS_CMD_RW_BIOSFW;
  701.       scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
  702.       scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
  703.       scb->cmd.flashfw.type = 1;
  704.       scb->cmd.flashfw.direction = 0;
  705.       scb->cmd.flashfw.count = cpu_to_le32(0x800);
  706.       scb->cmd.flashfw.buffer_addr = cpu_to_le32(VIRT_TO_BUS(buffer));
  707.       scb->cmd.flashfw.total_packets = 1;
  708.       scb->cmd.flashfw.packet_num = 0;
  709.       /* issue the command */
  710.       if (((ret = ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE) ||
  711.           (ret == IPS_SUCCESS_IMM) ||
  712.           ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
  713.          /* Error occurred */
  714.          kfree(buffer);
  715.          return;
  716.       }
  717.       if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
  718.          major    = buffer[0x1ff + 0xC0];  /* Offset 0x1ff after the header (0xc0) */
  719.          minor    = buffer[0x1fe + 0xC0];  /* Offset 0x1fe after the header (0xc0) */
  720.          subminor = buffer[0x1fd + 0xC0];  /* Offset 0x1fd after the header (0xc0) */
  721.       } else {
  722.          return;
  723.       }
  724.       kfree(buffer);
  725.    }
  726.    ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
  727.    ha->bios_version[1] = '.';
  728.    ha->bios_version[2] = hexDigits[major & 0x0F];
  729.    ha->bios_version[3] = hexDigits[subminor];
  730.    ha->bios_version[4] = '.';
  731.    ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
  732.    ha->bios_version[6] = hexDigits[minor & 0x0F];
  733.    ha->bios_version[7] = 0;
  734. }
  735. /****************************************************************************/
  736. /*                                                                          */
  737. /* Routine Name: ips_hainit                                                 */
  738. /*                                                                          */
  739. /* Routine Description:                                                     */
  740. /*                                                                          */
  741. /*   Initialize the controller                                              */
  742. /*                                                                          */
  743. /* NOTE: Assumes to be called from with a lock                              */
  744. /*                                                                          */
  745. /****************************************************************************/
  746. static int
  747. ips_hainit(ips_ha_t *ha) {
  748.    int            i;
  749.    struct timeval tv;
  750.    METHOD_TRACE("ips_hainit", 1);
  751.    if (!ha)
  752.       return (0);
  753.    if (ha->func.statinit)
  754.       (*ha->func.statinit)(ha);
  755.    if (ha->func.enableint)
  756.       (*ha->func.enableint)(ha);
  757.    /* Send FFDC */
  758.    ha->reset_count = 1;
  759.    do_gettimeofday(&tv);
  760.    ha->last_ffdc = tv.tv_sec;
  761.    ips_ffdc_reset(ha, IPS_INTR_IORL);
  762.    if (!ips_read_config(ha, IPS_INTR_IORL)) {
  763.       printk(KERN_WARNING "(%s%d) unable to read config from controller.n",
  764.              ips_name, ha->host_num);
  765.       return (0);
  766.    } /* end if */
  767.    if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
  768.       printk(KERN_WARNING "(%s%d) unable to read controller status.n",
  769.              ips_name, ha->host_num);
  770.       return (0);
  771.    }
  772.    /* Identify this controller */
  773.    ips_identify_controller(ha);
  774.    if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
  775.       printk(KERN_WARNING "(%s%d) unable to read subsystem parameters.n",
  776.              ips_name, ha->host_num);
  777.       return (0);
  778.    }
  779.    /* write nvram user page 5 */
  780.    if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
  781.       printk(KERN_WARNING "(%s%d) unable to write driver info to controller.n",
  782.              ips_name, ha->host_num);
  783.       return (0);
  784.    }
  785.    /* set limits on SID, LUN, BUS */
  786.    ha->ntargets = IPS_MAX_TARGETS + 1;
  787.    ha->nlun = 1;
  788.    ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
  789.    switch (ha->conf->logical_drive[0].ucStripeSize) {
  790.    case 4:
  791.       ha->max_xfer = 0x10000;
  792.       break;
  793.    case 5:
  794.       ha->max_xfer = 0x20000;
  795.       break;
  796.    case 6:
  797.       ha->max_xfer = 0x40000;
  798.       break;
  799.    case 7:
  800.    default:
  801.       ha->max_xfer = 0x80000;
  802.       break;
  803.    }
  804.    /* setup max concurrent commands */
  805.    if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
  806.       /* Use the new method */
  807.       ha->max_cmds = ha->enq->ucConcurrentCmdCount;
  808.    } else {
  809.       /* use the old method */
  810.       switch (ha->conf->logical_drive[0].ucStripeSize) {
  811.       case 4:
  812.          ha->max_cmds = 32;
  813.          break;
  814.       case 5:
  815.          ha->max_cmds = 16;
  816.          break;
  817.       case 6:
  818.          ha->max_cmds = 8;
  819.          break;
  820.       case 7:
  821.       default:
  822.          ha->max_cmds = 4;
  823.          break;
  824.       }
  825.    }
  826.    /* set controller IDs */
  827.    ha->ha_id[0] = IPS_ADAPTER_ID;
  828.    for (i = 1; i < ha->nbus; i++) {
  829.       ha->ha_id[i] = ha->conf->init_id[i-1] & 0x1f;
  830.       ha->dcdb_active[i-1] = 0;
  831.    }
  832.    return (1);
  833. }
  834. /****************************************************************************/
  835. /*                                                                          */
  836. /* Routine Name: ips_next                                                   */
  837. /*                                                                          */
  838. /* Routine Description:                                                     */
  839. /*                                                                          */
  840. /*   Take the next command off the queue and send it to the controller      */
  841. /*                                                                          */
  842. /****************************************************************************/
  843. static void
  844. ips_next(ips_ha_t *ha, int intr) {
  845.    ips_scb_t            *scb;
  846.    Scsi_Cmnd            *SC;
  847.    Scsi_Cmnd            *p;
  848.    Scsi_Cmnd            *q;
  849.    ips_copp_wait_item_t *item;
  850.    int                   ret;
  851.    int                   intr_status;
  852.    unsigned long         cpu_flags;
  853.    unsigned long         cpu_flags2;
  854.    METHOD_TRACE("ips_next", 1);
  855.    if (!ha)
  856.       return ;
  857.    /*
  858.     * Block access to the queue function so
  859.     * this command won't time out
  860.     */
  861.    if (intr == IPS_INTR_ON) {
  862.        spin_lock_irqsave(&io_request_lock, cpu_flags2);
  863.        intr_status = IPS_INTR_IORL;
  864.    } else {
  865.        intr_status = intr;
  866.        /* Quiet the compiler */
  867.        cpu_flags2 = 0;
  868.    }
  869.    if ((ha->subsys->param[3] & 0x300000)  && ( ha->scb_activelist.count == 0 )) {
  870.       struct timeval tv;
  871.       do_gettimeofday(&tv);
  872.       IPS_HA_LOCK(cpu_flags);
  873.       if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
  874.          ha->last_ffdc = tv.tv_sec;
  875.          IPS_HA_UNLOCK(cpu_flags);
  876.          ips_ffdc_time(ha, intr_status);
  877.       } else {
  878.          IPS_HA_UNLOCK(cpu_flags);
  879.       }
  880.    }
  881.    if (intr == IPS_INTR_ON)
  882.        spin_unlock_irqrestore(&io_request_lock, cpu_flags2);
  883. #ifndef NO_IPS_CMDLINE
  884.    /*
  885.     * Send passthru commands
  886.     * These have priority over normal I/O
  887.     * but shouldn't affect performance too much
  888.     * since we limit the number that can be active
  889.     * on the card at any one time
  890.     */
  891.    IPS_HA_LOCK(cpu_flags);
  892.    IPS_QUEUE_LOCK(&ha->copp_waitlist);
  893.    while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
  894.           (ha->copp_waitlist.head) &&
  895.           (scb = ips_getscb(ha))) {
  896.       IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
  897.       item = ips_removeq_copp_head(&ha->copp_waitlist);
  898.       ha->num_ioctl++;
  899.       IPS_HA_UNLOCK(cpu_flags);
  900.       scb->scsi_cmd = item->scsi_cmd;
  901.       scb->sem = item->sem;
  902.       kfree(item);
  903.       ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
  904.       switch (ret) {
  905.       case IPS_FAILURE:
  906.          if (scb->scsi_cmd) {
  907.             scb->scsi_cmd->result = DID_ERROR << 16;
  908.             /* raise the semaphore */
  909.             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
  910.                u_int32_t datasize;
  911.                datasize = 0;
  912.                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
  913.                up(&ha->ioctl_sem);
  914.             } else {
  915.                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  916.          }
  917.          }
  918.          ips_freescb(ha, scb);
  919.          break;
  920.       case IPS_SUCCESS_IMM:
  921.          if (scb->scsi_cmd) {
  922.             scb->scsi_cmd->result = DID_OK << 16;
  923.             /* raise the semaphore */
  924.             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
  925.                u_int32_t datasize;
  926.                datasize = 0;
  927.                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
  928.                up(&ha->ioctl_sem);
  929.             } else {
  930.                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  931.             }
  932.          }
  933.          ips_freescb(ha, scb);
  934.          break;
  935.       default:
  936.          break;
  937.       } /* end case */
  938.       if (ret != IPS_SUCCESS) {
  939.          IPS_HA_LOCK(cpu_flags);
  940.          IPS_QUEUE_LOCK(&ha->copp_waitlist);
  941.          ha->num_ioctl--;
  942.          continue;
  943.       }
  944.       ret = ips_send_cmd(ha, scb);
  945.       if (ret == IPS_SUCCESS) 
  946.          ips_putq_scb_head(&ha->scb_activelist, scb);
  947.       else
  948.          ha->num_ioctl--;
  949.       switch(ret) {
  950.       case IPS_FAILURE:
  951.          if (scb->scsi_cmd) {
  952.             /* raise the semaphore */
  953.             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
  954.                up(&ha->ioctl_sem);
  955.             scb->scsi_cmd->result = DID_ERROR << 16;
  956.          }
  957.          ips_freescb(ha, scb);
  958.          break;
  959.       case IPS_SUCCESS_IMM:
  960.          if (scb->scsi_cmd) {
  961.             /* raise the semaphore */
  962.             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND)
  963.                up(&ha->ioctl_sem);
  964.          }
  965.          ips_freescb(ha, scb);
  966.          break;
  967.       default:
  968.          break;
  969.       } /* end case */
  970.       IPS_HA_LOCK(cpu_flags);
  971.       IPS_QUEUE_LOCK(&ha->copp_waitlist);
  972.    }
  973.    IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
  974.    IPS_HA_UNLOCK(cpu_flags);
  975. #endif
  976.    /*
  977.     * Send "Normal" I/O commands
  978.     */
  979.    IPS_HA_LOCK(cpu_flags);
  980.    IPS_QUEUE_LOCK(&ha->scb_waitlist);
  981.    p = ha->scb_waitlist.head;
  982.    IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
  983.    while ((p) && (scb = ips_getscb(ha))) {
  984.       if ((p->channel > 0) && (ha->dcdb_active[p->channel-1] & (1 << p->target))) {
  985.          ips_freescb(ha, scb);
  986.          p = (Scsi_Cmnd *) p->host_scribble;
  987.          continue;
  988.       }
  989.       q = p;
  990.       SC = ips_removeq_wait(&ha->scb_waitlist, q);
  991.       if (SC == NULL)                    /* Should never happen, but good to check anyway */
  992.          continue;
  993.       IPS_HA_UNLOCK(cpu_flags);          /* Unlock HA after command is taken off queue */
  994.       SC->result = DID_OK;
  995.       SC->host_scribble = NULL;
  996.       memset(SC->sense_buffer, 0, sizeof(SC->sense_buffer));
  997.       scb->target_id = SC->target;
  998.       scb->lun = SC->lun;
  999.       scb->bus = SC->channel;
  1000.       scb->scsi_cmd = SC;
  1001.       scb->breakup = 0;
  1002.       scb->data_len = 0;
  1003.       scb->callback = ipsintr_done;
  1004.       scb->timeout = ips_cmd_timeout;
  1005.       memset(&scb->cmd, 0, 16);
  1006.       /* copy in the CDB */
  1007.       memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
  1008.       /* Now handle the data buffer */
  1009.       if (SC->use_sg) {
  1010.          struct scatterlist *sg;
  1011.          int                 i;
  1012.          sg = SC->request_buffer;
  1013.          if (SC->use_sg == 1) {
  1014.             if (sg[0].length > ha->max_xfer) {
  1015.                scb->breakup = 1;
  1016.                scb->data_len = ha->max_xfer;
  1017.             } else
  1018.                scb->data_len = sg[0].length;
  1019.             scb->dcdb.transfer_length = scb->data_len;
  1020.             scb->data_busaddr = VIRT_TO_BUS(sg[0].address);
  1021.             scb->sg_len = 0;
  1022.          } else {
  1023.             /* Check for the first Element being bigger than MAX_XFER */
  1024.             if (sg[0].length > ha->max_xfer) {
  1025.                scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[0].address));
  1026.                scb->sg_list[0].length = ha->max_xfer;
  1027.                scb->data_len = ha->max_xfer;
  1028.                scb->breakup = 0; 
  1029.                scb->sg_break=1;  
  1030.                scb->sg_len = 1;
  1031.             }
  1032.             else {
  1033.                for (i = 0; i < SC->use_sg; i++) {
  1034.                   scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
  1035.                   scb->sg_list[i].length = cpu_to_le32(sg[i].length);
  1036.             
  1037.                   if (scb->data_len + sg[i].length > ha->max_xfer) {
  1038.                      /*
  1039.                       * Data Breakup required
  1040.                       */
  1041.                      scb->breakup = i;
  1042.                      break;
  1043.                   }
  1044.                
  1045.                   scb->data_len += sg[i].length;
  1046.                }
  1047.                if (!scb->breakup)
  1048.                   scb->sg_len = SC->use_sg;
  1049.                else
  1050.                   scb->sg_len = scb->breakup;
  1051.             }
  1052.             scb->dcdb.transfer_length = scb->data_len;
  1053.             scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
  1054.          }
  1055.       } else {
  1056.          if (SC->request_bufflen) {
  1057.             if (SC->request_bufflen > ha->max_xfer) {
  1058.                /*
  1059.                 * Data breakup required
  1060.                 */
  1061.                scb->breakup = 1;
  1062.                scb->data_len = ha->max_xfer;
  1063.             } else {
  1064.                scb->data_len = SC->request_bufflen;
  1065.             }
  1066.             scb->dcdb.transfer_length = scb->data_len;
  1067.             scb->data_busaddr = VIRT_TO_BUS(SC->request_buffer);
  1068.             scb->sg_len = 0;
  1069.          } else {
  1070.             scb->data_busaddr = 0L;
  1071.             scb->sg_len = 0;
  1072.             scb->data_len = 0;
  1073.             scb->dcdb.transfer_length = 0;
  1074.          }
  1075.       }
  1076.       scb->dcdb.cmd_attribute |=
  1077.          ips_command_direction[scb->scsi_cmd->cmnd[0]];
  1078.       if (!scb->dcdb.cmd_attribute & 0x3)
  1079.          scb->dcdb.transfer_length = 0;
  1080.       if (scb->data_len >= IPS_MAX_XFER) {
  1081.          scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
  1082.          scb->dcdb.transfer_length = 0;
  1083.       }
  1084.       ret = ips_send_cmd(ha, scb);
  1085.       if (ret == IPS_SUCCESS)
  1086.          ips_putq_scb_head(&ha->scb_activelist, scb);
  1087.       switch(ret) {
  1088.       case IPS_FAILURE:
  1089.          if (scb->scsi_cmd) {
  1090.             scb->scsi_cmd->result = DID_ERROR << 16;
  1091.             scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  1092.          }
  1093.          if (scb->bus)
  1094.             ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
  1095.          ips_freescb(ha, scb);
  1096.          break;
  1097.       case IPS_SUCCESS_IMM:
  1098.          if (scb->scsi_cmd)
  1099.             scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  1100.          if (scb->bus)
  1101.             ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
  1102.          ips_freescb(ha, scb);
  1103.          break;
  1104.       default:
  1105.          break;
  1106.       } /* end case */
  1107.       p = (Scsi_Cmnd *) p->host_scribble;
  1108.       IPS_HA_LOCK(cpu_flags);
  1109.    } /* end while */
  1110.    IPS_HA_UNLOCK(cpu_flags);
  1111. }
  1112. /****************************************************************************/
  1113. /*                                                                          */
  1114. /* Routine Name: ips_putq_scb_head                                          */
  1115. /*                                                                          */
  1116. /* Routine Description:                                                     */
  1117. /*                                                                          */
  1118. /*   Add an item to the head of the queue                                   */
  1119. /*                                                                          */
  1120. /* ASSUMED to be called from within a lock                                  */
  1121. /*                                                                          */
  1122. /****************************************************************************/
  1123. static inline void
  1124. ips_putq_scb_head(ips_scb_queue_t *queue, ips_scb_t *item) {
  1125.    METHOD_TRACE("ips_putq_scb_head", 1);
  1126.    if (!item)
  1127.       return ;
  1128.    IPS_QUEUE_LOCK(queue);
  1129.    item->q_next = queue->head;
  1130.    queue->head = item;
  1131.    if (!queue->tail)
  1132.       queue->tail = item;
  1133.    queue->count++;
  1134.    IPS_QUEUE_UNLOCK(queue);
  1135. }
  1136. /****************************************************************************/
  1137. /*                                                                          */
  1138. /* Routine Name: ips_putq_scb_tail                                          */
  1139. /*                                                                          */
  1140. /* Routine Description:                                                     */
  1141. /*                                                                          */
  1142. /*   Add an item to the tail of the queue                                   */
  1143. /*                                                                          */
  1144. /* ASSUMED to be called from within a lock                                  */
  1145. /*                                                                          */
  1146. /****************************************************************************/
  1147. static inline void
  1148. ips_putq_scb_tail(ips_scb_queue_t *queue, ips_scb_t *item) {
  1149.    METHOD_TRACE("ips_putq_scb_tail", 1);
  1150.    if (!item)
  1151.       return ;
  1152.    IPS_QUEUE_LOCK(queue);
  1153.    item->q_next = NULL;
  1154.    if (queue->tail)
  1155.       queue->tail->q_next = item;
  1156.    queue->tail = item;
  1157.    if (!queue->head)
  1158.       queue->head = item;
  1159.    queue->count++;
  1160.    IPS_QUEUE_UNLOCK(queue);
  1161. }
  1162. /****************************************************************************/
  1163. /*                                                                          */
  1164. /* Routine Name: ips_removeq_scb_head                                       */
  1165. /*                                                                          */
  1166. /* Routine Description:                                                     */
  1167. /*                                                                          */
  1168. /*   Remove the head of the queue                                           */
  1169. /*                                                                          */
  1170. /* ASSUMED to be called from within a lock                                  */
  1171. /*                                                                          */
  1172. /****************************************************************************/
  1173. static inline ips_scb_t *
  1174. ips_removeq_scb_head(ips_scb_queue_t *queue) {
  1175.    ips_scb_t  *item;
  1176.    METHOD_TRACE("ips_removeq_scb_head", 1);
  1177.    IPS_QUEUE_LOCK(queue);
  1178.    item = queue->head;
  1179.    if (!item) {
  1180.       IPS_QUEUE_UNLOCK(queue);
  1181.       return (NULL);
  1182.    }
  1183.    queue->head = item->q_next;
  1184.    item->q_next = NULL;
  1185.    if (queue->tail == item)
  1186.       queue->tail = NULL;
  1187.    queue->count--;
  1188.    IPS_QUEUE_UNLOCK(queue);
  1189.    return (item);
  1190. }
  1191. /****************************************************************************/
  1192. /*                                                                          */
  1193. /* Routine Name: ips_removeq_scb                                            */
  1194. /*                                                                          */
  1195. /* Routine Description:                                                     */
  1196. /*                                                                          */
  1197. /*   Remove an item from a queue                                            */
  1198. /*                                                                          */
  1199. /* ASSUMED to be called from within a lock                                  */
  1200. /*                                                                          */
  1201. /****************************************************************************/
  1202. static inline ips_scb_t *
  1203. ips_removeq_scb(ips_scb_queue_t *queue, ips_scb_t *item) {
  1204.    ips_scb_t  *p;
  1205.    METHOD_TRACE("ips_removeq_scb", 1);
  1206.    if (!item)
  1207.       return (NULL);
  1208.    IPS_QUEUE_LOCK(queue);
  1209.    if (item == queue->head) {
  1210.       IPS_QUEUE_UNLOCK(queue);
  1211.       return (ips_removeq_scb_head(queue));
  1212.    }
  1213.    p = queue->head;
  1214.    while ((p) && (item != p->q_next))
  1215.       p = p->q_next;
  1216.    if (p) {
  1217.       /* found a match */
  1218.       p->q_next = item->q_next;
  1219.       if (!item->q_next)
  1220.          queue->tail = p;
  1221.       item->q_next = NULL;
  1222.       queue->count--;
  1223.       IPS_QUEUE_UNLOCK(queue);
  1224.       return (item);
  1225.    }
  1226.    IPS_QUEUE_UNLOCK(queue);
  1227.    return (NULL);
  1228. }
  1229. /****************************************************************************/
  1230. /*                                                                          */
  1231. /* Routine Name: ips_putq_wait_head                                         */
  1232. /*                                                                          */
  1233. /* Routine Description:                                                     */
  1234. /*                                                                          */
  1235. /*   Add an item to the head of the queue                                   */
  1236. /*                                                                          */
  1237. /* ASSUMED to be called from within a lock                                  */
  1238. /*                                                                          */
  1239. /****************************************************************************/
  1240. static inline void
  1241. ips_putq_wait_head(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
  1242.    METHOD_TRACE("ips_putq_wait_head", 1);
  1243.    if (!item)
  1244.       return ;
  1245.    IPS_QUEUE_LOCK(queue);
  1246.    item->host_scribble = (char *) queue->head;
  1247.    queue->head = item;
  1248.    if (!queue->tail)
  1249.       queue->tail = item;
  1250.    queue->count++;
  1251.    IPS_QUEUE_UNLOCK(queue);
  1252. }
  1253. /****************************************************************************/
  1254. /*                                                                          */
  1255. /* Routine Name: ips_putq_wait_tail                                         */
  1256. /*                                                                          */
  1257. /* Routine Description:                                                     */
  1258. /*                                                                          */
  1259. /*   Add an item to the tail of the queue                                   */
  1260. /*                                                                          */
  1261. /* ASSUMED to be called from within a lock                                  */
  1262. /*                                                                          */
  1263. /****************************************************************************/
  1264. static inline void
  1265. ips_putq_wait_tail(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
  1266.    METHOD_TRACE("ips_putq_wait_tail", 1);
  1267.    if (!item)
  1268.       return ;
  1269.    IPS_QUEUE_LOCK(queue);
  1270.    item->host_scribble = NULL;
  1271.    if (queue->tail)
  1272.       queue->tail->host_scribble = (char *)item;
  1273.    queue->tail = item;
  1274.    if (!queue->head)
  1275.       queue->head = item;
  1276.    queue->count++;
  1277.    IPS_QUEUE_UNLOCK(queue);
  1278. }
  1279. /****************************************************************************/
  1280. /*                                                                          */
  1281. /* Routine Name: ips_removeq_wait_head                                      */
  1282. /*                                                                          */
  1283. /* Routine Description:                                                     */
  1284. /*                                                                          */
  1285. /*   Remove the head of the queue                                           */
  1286. /*                                                                          */
  1287. /* ASSUMED to be called from within a lock                                  */
  1288. /*                                                                          */
  1289. /****************************************************************************/
  1290. static inline Scsi_Cmnd *
  1291. ips_removeq_wait_head(ips_wait_queue_t *queue) {
  1292.    Scsi_Cmnd  *item;
  1293.    METHOD_TRACE("ips_removeq_wait_head", 1);
  1294.    IPS_QUEUE_LOCK(queue);
  1295.    item = queue->head;
  1296.    if (!item) {
  1297.       IPS_QUEUE_UNLOCK(queue);
  1298.       return (NULL);
  1299.    }
  1300.    queue->head = (Scsi_Cmnd *) item->host_scribble;
  1301.    item->host_scribble = NULL;
  1302.    if (queue->tail == item)
  1303.       queue->tail = NULL;
  1304.    queue->count--;
  1305.    IPS_QUEUE_UNLOCK(queue);
  1306.    return (item);
  1307. }
  1308. /****************************************************************************/
  1309. /*                                                                          */
  1310. /* Routine Name: ips_removeq_wait                                           */
  1311. /*                                                                          */
  1312. /* Routine Description:                                                     */
  1313. /*                                                                          */
  1314. /*   Remove an item from a queue                                            */
  1315. /*                                                                          */
  1316. /* ASSUMED to be called from within a lock                                  */
  1317. /*                                                                          */
  1318. /****************************************************************************/
  1319. static inline Scsi_Cmnd *
  1320. ips_removeq_wait(ips_wait_queue_t *queue, Scsi_Cmnd *item) {
  1321.    Scsi_Cmnd  *p;
  1322.    METHOD_TRACE("ips_removeq_wait", 1);
  1323.    if (!item)
  1324.       return (NULL);
  1325.    IPS_QUEUE_LOCK(queue);
  1326.    if (item == queue->head) {
  1327.       IPS_QUEUE_UNLOCK(queue);
  1328.       return (ips_removeq_wait_head(queue));
  1329.    }
  1330.    p = queue->head;
  1331.    while ((p) && (item != (Scsi_Cmnd *) p->host_scribble))
  1332.       p = (Scsi_Cmnd *) p->host_scribble;
  1333.    if (p) {
  1334.       /* found a match */
  1335.       p->host_scribble = item->host_scribble;
  1336.       if (!item->host_scribble)
  1337.          queue->tail = p;
  1338.       item->host_scribble = NULL;
  1339.       queue->count--;
  1340.       IPS_QUEUE_UNLOCK(queue);
  1341.       return (item);
  1342.    }
  1343.    IPS_QUEUE_UNLOCK(queue);
  1344.    return (NULL);
  1345. }
  1346. /****************************************************************************/
  1347. /*                                                                          */
  1348. /* Routine Name: ips_putq_copp_head                                         */
  1349. /*                                                                          */
  1350. /* Routine Description:                                                     */
  1351. /*                                                                          */
  1352. /*   Add an item to the head of the queue                                   */
  1353. /*                                                                          */
  1354. /* ASSUMED to be called from within a lock                                  */
  1355. /*                                                                          */
  1356. /****************************************************************************/
  1357. static inline void
  1358. ips_putq_copp_head(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
  1359.    METHOD_TRACE("ips_putq_copp_head", 1);
  1360.    if (!item)
  1361.       return ;
  1362.    IPS_QUEUE_LOCK(queue);
  1363.    item->next = queue->head;
  1364.    queue->head = item;
  1365.    if (!queue->tail)
  1366.       queue->tail = item;
  1367.    queue->count++;
  1368.    IPS_QUEUE_UNLOCK(queue);
  1369. }
  1370. /****************************************************************************/
  1371. /*                                                                          */
  1372. /* Routine Name: ips_putq_copp_tail                                         */
  1373. /*                                                                          */
  1374. /* Routine Description:                                                     */
  1375. /*                                                                          */
  1376. /*   Add an item to the tail of the queue                                   */
  1377. /*                                                                          */
  1378. /* ASSUMED to be called from within a lock                                  */
  1379. /*                                                                          */
  1380. /****************************************************************************/
  1381. static inline void
  1382. ips_putq_copp_tail(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
  1383.    METHOD_TRACE("ips_putq_copp_tail", 1);
  1384.    if (!item)
  1385.       return ;
  1386.    IPS_QUEUE_LOCK(queue);
  1387.    item->next = NULL;
  1388.    if (queue->tail)
  1389.       queue->tail->next = item;
  1390.    queue->tail = item;
  1391.    if (!queue->head)
  1392.       queue->head = item;
  1393.    queue->count++;
  1394.    IPS_QUEUE_UNLOCK(queue);
  1395. }
  1396. /****************************************************************************/
  1397. /*                                                                          */
  1398. /* Routine Name: ips_removeq_copp_head                                      */
  1399. /*                                                                          */
  1400. /* Routine Description:                                                     */
  1401. /*                                                                          */
  1402. /*   Remove the head of the queue                                           */
  1403. /*                                                                          */
  1404. /* ASSUMED to be called from within a lock                                  */
  1405. /*                                                                          */
  1406. /****************************************************************************/
  1407. static inline ips_copp_wait_item_t *
  1408. ips_removeq_copp_head(ips_copp_queue_t *queue) {
  1409.    ips_copp_wait_item_t *item;
  1410.    METHOD_TRACE("ips_removeq_copp_head", 1);
  1411.    IPS_QUEUE_LOCK(queue);
  1412.    item = queue->head;
  1413.    if (!item) {
  1414.       IPS_QUEUE_UNLOCK(queue);
  1415.       return (NULL);
  1416.    }
  1417.    queue->head = item->next;
  1418.    item->next = NULL;
  1419.    if (queue->tail == item)
  1420.       queue->tail = NULL;
  1421.    queue->count--;
  1422.    IPS_QUEUE_UNLOCK(queue);
  1423.    return (item);
  1424. }
  1425. /****************************************************************************/
  1426. /*                                                                          */
  1427. /* Routine Name: ips_removeq_copp                                           */
  1428. /*                                                                          */
  1429. /* Routine Description:                                                     */
  1430. /*                                                                          */
  1431. /*   Remove an item from a queue                                            */
  1432. /*                                                                          */
  1433. /* ASSUMED to be called from within a lock                                  */
  1434. /*                                                                          */
  1435. /****************************************************************************/
  1436. static inline ips_copp_wait_item_t *
  1437. ips_removeq_copp(ips_copp_queue_t *queue, ips_copp_wait_item_t *item) {
  1438.    ips_copp_wait_item_t *p;
  1439.    METHOD_TRACE("ips_removeq_copp", 1);
  1440.    if (!item)
  1441.       return (NULL);
  1442.    IPS_QUEUE_LOCK(queue);
  1443.    if (item == queue->head) {
  1444.       IPS_QUEUE_UNLOCK(queue);
  1445.       return (ips_removeq_copp_head(queue));
  1446.    }
  1447.    p = queue->head;
  1448.    while ((p) && (item != p->next))
  1449.       p = p->next;
  1450.    if (p) {
  1451.       /* found a match */
  1452.       p->next = item->next;
  1453.       if (!item->next)
  1454.          queue->tail = p;
  1455.       item->next = NULL;
  1456.       queue->count--;
  1457.       IPS_QUEUE_UNLOCK(queue);
  1458.       return (item);
  1459.    }
  1460.    IPS_QUEUE_UNLOCK(queue);
  1461.    return (NULL);
  1462. }
  1463. /****************************************************************************/
  1464. /*                                                                          */
  1465. /* Routine Name: ipsintr_blocking                                           */
  1466. /*                                                                          */
  1467. /* Routine Description:                                                     */
  1468. /*                                                                          */
  1469. /*   Finalize an interrupt for internal commands                            */
  1470. /*                                                                          */
  1471. /****************************************************************************/
  1472. static void
  1473. ipsintr_blocking(ips_ha_t *ha, ips_scb_t *scb) {
  1474.    METHOD_TRACE("ipsintr_blocking", 2);
  1475.    if ((ha->waitflag == TRUE) &&
  1476.        (ha->cmd_in_progress == scb->cdb[0])) {
  1477.       ha->waitflag = FALSE;
  1478.       return ;
  1479.    }
  1480. }
  1481. /****************************************************************************/
  1482. /*                                                                          */
  1483. /* Routine Name: ipsintr_done                                               */
  1484. /*                                                                          */
  1485. /* Routine Description:                                                     */
  1486. /*                                                                          */
  1487. /*   Finalize an interrupt for non-internal commands                        */
  1488. /*                                                                          */
  1489. /****************************************************************************/
  1490. static void
  1491. ipsintr_done(ips_ha_t *ha, ips_scb_t *scb) {
  1492.    METHOD_TRACE("ipsintr_done", 2);
  1493.    if (!scb) {
  1494.       printk(KERN_WARNING "(%s%d) Spurious interrupt; scb NULL.n",
  1495.              ips_name, ha->host_num);
  1496.       return ;
  1497.    }
  1498.    if (scb->scsi_cmd == NULL) {
  1499.       /* unexpected interrupt */
  1500.       printk(KERN_WARNING "(%s%d) Spurious interrupt; scsi_cmd not set.n",
  1501.              ips_name, ha->host_num);
  1502.       return;
  1503.    }
  1504.    ips_done(ha, scb);
  1505. }
  1506. /****************************************************************************/
  1507. /*                                                                          */
  1508. /* Routine Name: ips_done                                                   */
  1509. /*                                                                          */
  1510. /* Routine Description:                                                     */
  1511. /*                                                                          */
  1512. /*   Do housekeeping on completed commands                                  */
  1513. /*                                                                          */
  1514. /****************************************************************************/
  1515. static void
  1516. ips_done(ips_ha_t *ha, ips_scb_t *scb) {
  1517.    int ret;
  1518.    unsigned long cpu_flags;
  1519.    METHOD_TRACE("ips_done", 1);
  1520.    if (!scb)
  1521.       return ;
  1522. #ifndef NO_IPS_CMDLINE
  1523.    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
  1524.       ips_cleanup_passthru(ha, scb);
  1525.       IPS_HA_LOCK(cpu_flags);
  1526.       ha->num_ioctl--;
  1527.       IPS_HA_UNLOCK(cpu_flags);
  1528.    } else {
  1529. #endif
  1530.       /*
  1531.        * Check to see if this command had too much
  1532.        * data and had to be broke up.  If so, queue
  1533.        * the rest of the data and continue.
  1534.        */
  1535.       if (scb->breakup) {
  1536.          /* we had a data breakup */
  1537.          u_int8_t bk_save;
  1538.          bk_save = scb->breakup;
  1539.          scb->breakup = 0;
  1540.          if (scb->scsi_cmd->use_sg) {
  1541.             /* S/G request */
  1542.             struct scatterlist *sg;
  1543.             int                 i;
  1544.             sg = scb->scsi_cmd->request_buffer;
  1545.             if (scb->scsi_cmd->use_sg == 1) {
  1546.                if (sg[0].length - (bk_save * ha->max_xfer) > ha->max_xfer) {
  1547.                   /* Further breakup required */
  1548.                   scb->data_len = ha->max_xfer;
  1549.                   scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
  1550.                   scb->breakup = bk_save + 1;
  1551.                } else {
  1552.                   scb->data_len = sg[0].length - (bk_save * ha->max_xfer);
  1553.                   scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
  1554.                }
  1555.                scb->dcdb.transfer_length = scb->data_len;
  1556.                scb->sg_len = 0;
  1557.             } else {
  1558.                /* We're here because there was MORE than one s/g unit. */
  1559.             /* bk_save points to which sg unit to look at           */
  1560.             /* sg_break points to how far through this unit we are  */
  1561.             /* NOTE: We will not move from one sg to another here,  */
  1562.                /*    just finish the one we are in.  Not the most      */
  1563.                /*    efficient, but it keeps it from getting too hacky */
  1564.          /* IF sg_break is non-zero, then just work on this current sg piece, */
  1565.                /* pointed to by bk_save                                             */
  1566.                if (scb->sg_break) {
  1567.                   scb->sg_len = 1;
  1568.             scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address+ha->max_xfer*scb->sg_break);
  1569.                   if (ha->max_xfer > sg[bk_save].length-ha->max_xfer * scb->sg_break) 
  1570.                      scb->sg_list[0].length = sg[bk_save].length-ha->max_xfer * scb->sg_break;
  1571.                   else 
  1572.                      scb->sg_list[0].length = ha->max_xfer;
  1573.                   scb->sg_break++;              /* MUST GO HERE for math below to work */
  1574.          scb->data_len = scb->sg_list[0].length;;
  1575.             if (sg[bk_save].length <= ha->max_xfer * scb->sg_break ) {
  1576.                      scb->sg_break = 0;         /* No more work in this unit */
  1577.                      if (( bk_save + 1 ) >= scb->scsi_cmd->use_sg) 
  1578.                         scb->breakup = 0;
  1579.                      else 
  1580.                         scb->breakup = bk_save + 1;
  1581.                   }
  1582.                } else {
  1583.          /* ( sg_break == 0 ), so this is our first look at a new sg piece */
  1584.                   if (sg[bk_save].length > ha->max_xfer) {
  1585.             scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[bk_save].address));
  1586.          scb->sg_list[0].length = ha->max_xfer;
  1587.          scb->breakup = bk_save;
  1588.          scb->sg_break = 1;
  1589.          scb->data_len = ha->max_xfer;
  1590.          scb->sg_len = 1;
  1591.               } else {
  1592.          /* OK, the next sg is a short one, so loop until full */
  1593.             scb->data_len = 0;
  1594.                scb->sg_len = 0;
  1595.              scb->sg_break = 0;
  1596.                      /*   We're only doing full units here */
  1597.          for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
  1598.          scb->sg_list[i - bk_save].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
  1599.             scb->sg_list[i - bk_save].length = cpu_to_le32(sg[i].length);
  1600.                         if (scb->data_len + sg[i].length > ha->max_xfer) {
  1601.             scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
  1602.             break;
  1603.          }
  1604.          scb->data_len += sg[i].length;
  1605.          scb->sg_len++;           /* only if we didn't get too big */
  1606.             }
  1607.          }
  1608.          }
  1609.                /* Also, we need to be sure we don't queue work ( breakup != 0 )
  1610.                   if no more sg units for next time */
  1611.                scb->dcdb.transfer_length = scb->data_len;
  1612.                scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
  1613.             }
  1614.                                               
  1615.              } else {
  1616.             /* Non S/G Request */
  1617.             if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
  1618.                /* Further breakup required */
  1619.                scb->data_len = ha->max_xfer;
  1620.                scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
  1621.                scb->breakup = bk_save + 1;
  1622.             } else {
  1623.                scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer);
  1624.                scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
  1625.             }
  1626.             scb->dcdb.transfer_length = scb->data_len;
  1627.             scb->sg_len = 0;
  1628.          }
  1629.          scb->dcdb.cmd_attribute |=
  1630.             ips_command_direction[scb->scsi_cmd->cmnd[0]];
  1631.          if (!scb->dcdb.cmd_attribute & 0x3)
  1632.             scb->dcdb.transfer_length = 0;
  1633.          if (scb->data_len >= IPS_MAX_XFER) {
  1634.             scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
  1635.             scb->dcdb.transfer_length = 0;
  1636.          }
  1637.          ret = ips_send_cmd(ha, scb);
  1638.          switch(ret) {
  1639.          case IPS_FAILURE:
  1640.             if (scb->scsi_cmd) {
  1641.                scb->scsi_cmd->result = DID_ERROR << 16;
  1642.                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  1643.             }
  1644.             ips_freescb(ha, scb);
  1645.             break;
  1646.          case IPS_SUCCESS_IMM:
  1647.             if (scb->scsi_cmd) {
  1648.                scb->scsi_cmd->result = DID_ERROR << 16;
  1649.                scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  1650.             }
  1651.             ips_freescb(ha, scb);
  1652.             break;
  1653.          default:
  1654.             break;
  1655.          } /* end case */
  1656.          return ;
  1657.       }
  1658. #ifndef NO_IPS_CMDLINE
  1659.    } /* end if passthru */
  1660. #endif
  1661.    if (scb->bus) {
  1662.       IPS_HA_LOCK(cpu_flags);
  1663.       ha->dcdb_active[scb->bus-1] &= ~(1 << scb->target_id);
  1664.       IPS_HA_UNLOCK(cpu_flags);
  1665.    }
  1666.    /* call back to SCSI layer */
  1667.    if (scb->scsi_cmd && scb->scsi_cmd->cmnd[0] != IPS_IOCTL_NEW_COMMAND)
  1668.       scb->scsi_cmd->scsi_done(scb->scsi_cmd);
  1669.    ips_freescb(ha, scb);
  1670. }
  1671. /****************************************************************************/
  1672. /*                                                                          */
  1673. /* Routine Name: ips_map_status                                             */
  1674. /*                                                                          */
  1675. /* Routine Description:                                                     */
  1676. /*                                                                          */
  1677. /*   Map ServeRAID error codes to Linux Error Codes                         */
  1678. /*                                                                          */
  1679. /****************************************************************************/
  1680. static int
  1681. ips_map_status(ips_ha_t *ha, ips_scb_t *scb, ips_stat_t *sp) {
  1682.    int       errcode;
  1683.    int       device_error;
  1684.    METHOD_TRACE("ips_map_status", 1);
  1685.    if (scb->bus) {
  1686.       DEBUG_VAR(2, "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
  1687.                 ips_name,
  1688.                 ha->host_num,
  1689.                 scb->scsi_cmd->channel,
  1690.                 scb->scsi_cmd->target,
  1691.                 scb->scsi_cmd->lun,
  1692.                 scb->basic_status,
  1693.                 scb->extended_status,
  1694.                 scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
  1695.                 scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
  1696.                 scb->extended_status == IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
  1697.    }
  1698.    /* default driver error */
  1699.    errcode = DID_ERROR;
  1700.    device_error = 0;
  1701.    switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
  1702.    case IPS_CMD_TIMEOUT:
  1703.       errcode = DID_TIME_OUT;
  1704.       break;
  1705.    case IPS_INVAL_OPCO:
  1706.    case IPS_INVAL_CMD_BLK:
  1707.    case IPS_INVAL_PARM_BLK:
  1708.    case IPS_LD_ERROR:
  1709.    case IPS_CMD_CMPLT_WERROR:
  1710.       break;
  1711.    case IPS_PHYS_DRV_ERROR:
  1712.       switch (scb->extended_status) {
  1713.       case IPS_ERR_SEL_TO:
  1714.          if (scb->bus)
  1715.             errcode = DID_NO_CONNECT;
  1716.          break;
  1717.       case IPS_ERR_OU_RUN:
  1718.          if ((scb->bus) && (scb->dcdb.transfer_length < scb->data_len)) {
  1719.             /* Underrun - set default to no error */
  1720.             errcode = DID_OK;
  1721.             /* Restrict access to physical DASD */
  1722.             if ((scb->scsi_cmd->cmnd[0] == INQUIRY) &&
  1723.                 ((((char *) scb->scsi_cmd->buffer)[0] & 0x1f) == TYPE_DISK)) {
  1724.                /* underflow -- no error               */
  1725.                /* restrict access to physical DASD    */
  1726.                errcode = DID_TIME_OUT;
  1727.                break;
  1728.             }
  1729.          } else
  1730.             errcode = DID_ERROR;
  1731.          break;
  1732.       case IPS_ERR_RECOVERY:
  1733.          /* don't fail recovered errors */
  1734.          if (scb->bus)
  1735.             errcode = DID_OK;
  1736.          break;
  1737.       case IPS_ERR_HOST_RESET:
  1738.       case IPS_ERR_DEV_RESET:
  1739.          errcode = DID_RESET;
  1740.          break;
  1741.       case IPS_ERR_CKCOND:
  1742.          if (scb->bus) {
  1743.             memcpy(scb->scsi_cmd->sense_buffer, scb->dcdb.sense_info,
  1744.                    sizeof(scb->scsi_cmd->sense_buffer));
  1745.             device_error = 2; /* check condition */
  1746.          }
  1747.          errcode = DID_OK;
  1748.          break;
  1749.       default:
  1750.          errcode = DID_ERROR;
  1751.          break;
  1752.       } /* end switch */
  1753.    } /* end switch */
  1754.    scb->scsi_cmd->result = device_error | (errcode << 16);
  1755.    return (1);
  1756. }
  1757. /****************************************************************************/
  1758. /*                                                                          */
  1759. /* Routine Name: ips_send                                                   */
  1760. /*                                                                          */
  1761. /* Routine Description:                                                     */
  1762. /*                                                                          */
  1763. /*   Wrapper for ips_send_cmd                                               */
  1764. /*                                                                          */
  1765. /****************************************************************************/
  1766. static int
  1767. ips_send(ips_ha_t *ha, ips_scb_t *scb, ips_scb_callback callback) {
  1768.    int ret;
  1769.    METHOD_TRACE("ips_send", 1);
  1770.    scb->callback = callback;
  1771.    ret = ips_send_cmd(ha, scb);
  1772.    return (ret);
  1773. }
  1774. /****************************************************************************/
  1775. /*                                                                          */
  1776. /* Routine Name: ips_send_wait                                              */
  1777. /*                                                                          */
  1778. /* Routine Description:                                                     */
  1779. /*                                                                          */
  1780. /*   Send a command to the controller and wait for it to return             */
  1781. /*                                                                          */
  1782. /****************************************************************************/
  1783. static int
  1784. ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
  1785.    int       ret;
  1786.    METHOD_TRACE("ips_send_wait", 1);
  1787.    ha->waitflag = TRUE;
  1788.    ha->cmd_in_progress = scb->cdb[0];
  1789.    ret = ips_send(ha, scb, ipsintr_blocking);
  1790.    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
  1791.       return (ret);
  1792.    ret = ips_wait(ha, timeout, intr);
  1793.    return (ret);
  1794. }
  1795. /****************************************************************************/
  1796. /*                                                                          */
  1797. /* Routine Name: ips_send_cmd                                               */
  1798. /*                                                                          */
  1799. /* Routine Description:                                                     */
  1800. /*                                                                          */
  1801. /*   Map SCSI commands to ServeRAID commands for logical drives             */
  1802. /*                                                                          */
  1803. /****************************************************************************/
  1804. static int
  1805. ips_send_cmd(ips_ha_t *ha, ips_scb_t *scb) {
  1806.    int       ret;
  1807.    char     *sp;
  1808.    int       device_error;
  1809.    METHOD_TRACE("ips_send_cmd", 1);
  1810.    ret = IPS_SUCCESS;
  1811.    if (!scb->scsi_cmd) {
  1812.       /* internal command */
  1813.       if (scb->bus > 0) {
  1814.          /* ServeRAID commands can't be issued */
  1815.          /* to real devices -- fail them       */
  1816.          if ((ha->waitflag == TRUE) &&
  1817.              (ha->cmd_in_progress == scb->cdb[0])) {
  1818.             ha->waitflag = FALSE;
  1819.          }
  1820.          return (1);
  1821.       }
  1822. #ifndef NO_IPS_CMDLINE
  1823.    } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
  1824. #else
  1825.    } else if (scb->bus == 0) {
  1826. #endif
  1827.       /* command to logical bus -- interpret */
  1828.       ret = IPS_SUCCESS_IMM;
  1829.       switch (scb->scsi_cmd->cmnd[0]) {
  1830.       case ALLOW_MEDIUM_REMOVAL:
  1831.       case REZERO_UNIT:
  1832.       case ERASE:
  1833.       case WRITE_FILEMARKS:
  1834.       case SPACE:
  1835.          scb->scsi_cmd->result = DID_ERROR << 16;
  1836.          break;
  1837.       case START_STOP:
  1838.          scb->scsi_cmd->result = DID_OK << 16;
  1839.       case TEST_UNIT_READY:
  1840.       case INQUIRY:
  1841.          if (scb->target_id == IPS_ADAPTER_ID) {
  1842.             /*
  1843.              * Either we have a TUR
  1844.              * or we have a SCSI inquiry
  1845.              */
  1846.             if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
  1847.                scb->scsi_cmd->result = DID_OK << 16;
  1848.             if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
  1849.                IPS_SCSI_INQ_DATA inquiry;
  1850.                memset(&inquiry, 0, sizeof(IPS_SCSI_INQ_DATA));
  1851.                inquiry.DeviceType = IPS_SCSI_INQ_TYPE_PROCESSOR;
  1852.                inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
  1853.                inquiry.Version = IPS_SCSI_INQ_REV2;
  1854.                inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
  1855.                inquiry.AdditionalLength = 31;
  1856.                inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
  1857.                inquiry.Flags[1] = IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync;
  1858.                strncpy(inquiry.VendorId, "IBM     ", 8);
  1859.                strncpy(inquiry.ProductId, "SERVERAID       ", 16);
  1860.                strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
  1861.                memcpy(scb->scsi_cmd->request_buffer, &inquiry, scb->scsi_cmd->request_bufflen);
  1862.                scb->scsi_cmd->result = DID_OK << 16;
  1863.             }
  1864.          } else {
  1865.             scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
  1866.             scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
  1867.             scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info));
  1868.             scb->cmd.logical_info.reserved = 0;
  1869.             scb->cmd.logical_info.reserved2 = 0;
  1870.             ret = IPS_SUCCESS;
  1871.          }
  1872.          break;
  1873.       case REQUEST_SENSE:
  1874.          ips_reqsen(ha, scb);
  1875.          scb->scsi_cmd->result = DID_OK << 16;
  1876.          break;
  1877.       case READ_6:
  1878.       case WRITE_6:
  1879.          if (!scb->sg_len) {
  1880.             scb->cmd.basic_io.op_code =
  1881.             (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
  1882.          } else {
  1883.             scb->cmd.basic_io.op_code =
  1884.             (scb->scsi_cmd->cmnd[0] == READ_6) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
  1885.          }
  1886.          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
  1887.          scb->cmd.basic_io.log_drv = scb->target_id;
  1888.          scb->cmd.basic_io.sg_count = scb->sg_len;
  1889.          scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
  1890.          if (scb->cmd.basic_io.lba)
  1891.             scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
  1892.                                                 le16_to_cpu(scb->cmd.basic_io.sector_count));
  1893.          else
  1894.             scb->cmd.basic_io.lba = (((scb->scsi_cmd->cmnd[1] & 0x1f) << 16) |
  1895.                                      (scb->scsi_cmd->cmnd[2] << 8) |
  1896.                                      (scb->scsi_cmd->cmnd[3]));
  1897.          scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
  1898.          if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
  1899.             scb->cmd.basic_io.sector_count = cpu_to_le16(256);
  1900.          scb->cmd.basic_io.reserved = 0;
  1901.          ret = IPS_SUCCESS;
  1902.          break;
  1903.       case READ_10:
  1904.       case WRITE_10:
  1905.          if (!scb->sg_len) {
  1906.             scb->cmd.basic_io.op_code =
  1907.             (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
  1908.          } else {
  1909.             scb->cmd.basic_io.op_code =
  1910.             (scb->scsi_cmd->cmnd[0] == READ_10) ? IPS_CMD_READ_SG : IPS_CMD_WRITE_SG;
  1911.          }
  1912.          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
  1913.          scb->cmd.basic_io.log_drv = scb->target_id;
  1914.          scb->cmd.basic_io.sg_count = scb->sg_len;
  1915.          scb->cmd.basic_io.sg_addr = cpu_to_le32(scb->data_busaddr);
  1916.          if (scb->cmd.basic_io.lba)
  1917.             scb->cmd.basic_io.lba = cpu_to_le32(le32_to_cpu(scb->cmd.basic_io.lba) +
  1918.                                                 le16_to_cpu(scb->cmd.basic_io.sector_count));
  1919.          else
  1920.             scb->cmd.basic_io.lba = ((scb->scsi_cmd->cmnd[2] << 24) |
  1921.                                      (scb->scsi_cmd->cmnd[3] << 16) |
  1922.                                      (scb->scsi_cmd->cmnd[4] << 8) |
  1923.                                      scb->scsi_cmd->cmnd[5]);
  1924.          scb->cmd.basic_io.sector_count = cpu_to_le16(scb->data_len / IPS_BLKSIZE);
  1925.          scb->cmd.basic_io.reserved = 0;
  1926.          if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
  1927.             /*
  1928.              * This is a null condition
  1929.              * we don't have to do anything
  1930.              * so just return
  1931.              */
  1932.             scb->scsi_cmd->result = DID_OK << 16;
  1933.          } else
  1934.             ret = IPS_SUCCESS;
  1935.          break;
  1936.       case RESERVE:
  1937.       case RELEASE:
  1938.          scb->scsi_cmd->result = DID_OK << 16;
  1939.          break;
  1940.       case MODE_SENSE:
  1941.          scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
  1942.          scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
  1943.          scb->cmd.basic_io.sg_addr = cpu_to_le32(VIRT_TO_BUS(ha->enq));
  1944.          ret = IPS_SUCCESS;
  1945.          break;
  1946.       case READ_CAPACITY:
  1947.          scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
  1948.          scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
  1949.          scb->cmd.logical_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(&ha->adapt->logical_drive_info));
  1950.          scb->cmd.logical_info.reserved = 0;
  1951.          scb->cmd.logical_info.reserved2 = 0;
  1952.          scb->cmd.logical_info.reserved3 = 0;
  1953.          ret = IPS_SUCCESS;
  1954.          break;
  1955.       case SEND_DIAGNOSTIC:
  1956.       case REASSIGN_BLOCKS:
  1957.       case FORMAT_UNIT:
  1958.       case SEEK_10:
  1959.       case VERIFY:
  1960.       case READ_DEFECT_DATA:
  1961.       case READ_BUFFER:
  1962.       case WRITE_BUFFER:
  1963.          scb->scsi_cmd->result = DID_OK << 16;
  1964.          break;
  1965.       default:
  1966.          /* Set the Return Info to appear like the Command was */
  1967.          /* attempted, a Check Condition occurred, and Sense   */
  1968.          /* Data indicating an Invalid CDB OpCode is returned. */
  1969.          sp = (char *) scb->scsi_cmd->sense_buffer;
  1970.          memset(sp, 0, sizeof(scb->scsi_cmd->sense_buffer));
  1971.   
  1972.          sp[0] = 0x70;             /* Error Code               */ 
  1973.          sp[2] = ILLEGAL_REQUEST;  /* Sense Key 5 Illegal Req. */
  1974.          sp[7] = 0x0A;             /* Additional Sense Length  */
  1975.          sp[12] = 0x20;            /* ASC = Invalid OpCode     */
  1976.          sp[13] = 0x00;            /* ASCQ                     */
  1977.    
  1978.          device_error = 2;         /* Indicate Check Condition */
  1979.          scb->scsi_cmd->result = device_error | (DID_OK << 16);
  1980.          break;
  1981.       } /* end switch */
  1982.    } /* end if */
  1983.    if (ret == IPS_SUCCESS_IMM)
  1984.       return (ret);
  1985.    /* setup DCDB */
  1986.    if (scb->bus > 0) {
  1987.       if (!scb->sg_len)
  1988.          scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
  1989.       else
  1990.          scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
  1991.       /* If we already know the Device is Not there, no need to attempt a Command   */
  1992.       /* This also protects an NT FailOver Controller from getting CDB's sent to it */
  1993.       if ( ha->conf->dev[scb->bus-1][scb->target_id].ucState == 0 ) {
  1994.          scb->scsi_cmd->result = DID_NO_CONNECT << 16;
  1995.          return (IPS_SUCCESS_IMM); 
  1996.       }
  1997.       ha->dcdb_active[scb->bus-1] |= (1 << scb->target_id);
  1998.       scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
  1999.       scb->cmd.dcdb.dcdb_address = cpu_to_le32(VIRT_TO_BUS(&scb->dcdb));
  2000.       scb->cmd.dcdb.reserved = 0;
  2001.       scb->cmd.dcdb.reserved2 = 0;
  2002.       scb->cmd.dcdb.reserved3 = 0;
  2003.       scb->dcdb.device_address = ((scb->bus - 1) << 4) | scb->target_id;
  2004.       scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
  2005.       if (scb->timeout) {
  2006.          if (scb->timeout <= 10)
  2007.             scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
  2008.          else if (scb->timeout <= 60)
  2009.             scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
  2010.          else
  2011.             scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
  2012.       }
  2013.       if (!(scb->dcdb.cmd_attribute & IPS_TIMEOUT20M))
  2014.          scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
  2015.       scb->dcdb.sense_length = sizeof(scb->scsi_cmd->sense_buffer);
  2016.       scb->dcdb.buffer_pointer = cpu_to_le32(scb->data_busaddr);
  2017.       scb->dcdb.sg_count = scb->sg_len;
  2018.       scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
  2019.       memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd, scb->scsi_cmd->cmd_len);
  2020.    }
  2021.    return ((*ha->func.issue)(ha, scb));
  2022. }
  2023. /****************************************************************************/
  2024. /*                                                                          */
  2025. /* Routine Name: ips_chk_status                                             */
  2026. /*                                                                          */
  2027. /* Routine Description:                                                     */
  2028. /*                                                                          */
  2029. /*   Check the status of commands to logical drives                         */
  2030. /*                                                                          */
  2031. /****************************************************************************/
  2032. static void
  2033. ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
  2034.    ips_scb_t  *scb;
  2035.    ips_stat_t *sp;
  2036.    u_int8_t    basic_status;
  2037.    u_int8_t    ext_status;
  2038.    int         errcode;
  2039.    METHOD_TRACE("ips_chkstatus", 1);
  2040.    scb = &ha->scbs[pstatus->fields.command_id];
  2041.    scb->basic_status = basic_status = pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
  2042.    scb->extended_status = ext_status = pstatus->fields.extended_status;
  2043.    sp = &ha->sp;
  2044.    sp->residue_len = 0;
  2045.    sp->scb_addr = (void *) scb;