linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / scsi / aacraid / aachba.c
index 83b5c7d..a16f8de 100644 (file)
@@ -32,7 +32,6 @@
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
-#include <linux/dma-mapping.h>
 #include <asm/semaphore.h>
 #include <asm/uaccess.h>
 
@@ -148,27 +147,21 @@ static int nondasd = -1;
 static int dacmode = -1;
 
 static int commit = -1;
-int startup_timeout = 180;
-int aif_timeout = 120;
 
-module_param(nondasd, int, S_IRUGO|S_IWUSR);
+module_param(nondasd, int, 0);
 MODULE_PARM_DESC(nondasd, "Control scanning of hba for nondasd devices. 0=off, 1=on");
-module_param(dacmode, int, S_IRUGO|S_IWUSR);
+module_param(dacmode, int, 0);
 MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC. 0=off, 1=on");
-module_param(commit, int, S_IRUGO|S_IWUSR);
+module_param(commit, int, 0);
 MODULE_PARM_DESC(commit, "Control whether a COMMIT_CONFIG is issued to the adapter for foreign arrays.\nThis is typically needed in systems that do not have a BIOS. 0=off, 1=on");
-module_param(startup_timeout, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(startup_timeout, "The duration of time in seconds to wait for adapter to have it's kernel up and\nrunning. This is typically adjusted for large systems that do not have a BIOS.");
-module_param(aif_timeout, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(aif_timeout, "The duration of time in seconds to wait for applications to pick up AIFs before\nderegistering them. This is typically adjusted for heavily burdened systems.");
 
 int numacb = -1;
 module_param(numacb, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid values are 512 and down. Default is to use suggestion from Firmware.");
+MODULE_PARM_DESC(numacb, "Request a limit to the number of adapter control blocks (FIB) allocated. Valid\nvalues are 512 and down. Default is to use suggestion from Firmware.");
 
 int acbsize = -1;
 module_param(acbsize, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512, 2048, 4096 and 8192. Default is to use suggestion from Firmware.");
+MODULE_PARM_DESC(acbsize, "Request a specific adapter control block (FIB) size. Valid values are 512,\n2048, 4096 and 8192. Default is to use suggestion from Firmware.");
 /**
  *     aac_get_config_status   -       check the adapter configuration
  *     @common: adapter to query
@@ -393,10 +386,10 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
        struct scsi_cmnd * scsicmd;
 
        scsicmd = (struct scsi_cmnd *) context;
-       scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
 
        dprintk((KERN_DEBUG "get_container_name_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
-       BUG_ON(fibptr == NULL);
+       if (fibptr == NULL)
+               BUG();
 
        get_name_reply = (struct aac_get_name_resp *) fib_data(fibptr);
        /* Failure is irrelevant, using default value instead */
@@ -459,10 +452,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Check that the command queued to the controller
         */
-       if (status == -EINPROGRESS) {
-               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+       if (status == -EINPROGRESS) 
                return 0;
-       }
                
        printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status);
        aac_fib_complete(cmd_fibcontext);
@@ -640,13 +631,13 @@ static void setinqstr(struct aac_dev *dev, void *data, int tindex)
                        cp[sizeof(str->pid)] = c;
        } else {
                struct aac_driver_ident *mp = aac_get_driver_ident(dev->cardtype);
-
-               inqstrcpy (mp->vname, str->vid);
+   
+               inqstrcpy (mp->vname, str->vid); 
                /* last six chars reserved for vol type */
                inqstrcpy (mp->model, str->pid);
        }
 
-       if (tindex < ARRAY_SIZE(container_types)){
+       if (tindex < (sizeof(container_types)/sizeof(char *))){
                char *findit = str->pid;
 
                for ( ; *findit != ' '; findit++); /* walk till we find a space */
@@ -915,10 +906,9 @@ static void io_callback(void *context, struct fib * fibptr)
        u32 cid;
 
        scsicmd = (struct scsi_cmnd *) context;
-       scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
 
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
-       cid = scmd_id(scsicmd);
+       cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
        if (nblank(dprintk(x))) {
                u64 lba;
@@ -955,11 +945,12 @@ static void io_callback(void *context, struct fib * fibptr)
                  smp_processor_id(), (unsigned long long)lba, jiffies);
        }
 
-       BUG_ON(fibptr == NULL);
+       if (fibptr == NULL)
+               BUG();
                
        if(scsicmd->use_sg)
                pci_unmap_sg(dev->pdev, 
-                       (struct scatterlist *)scsicmd->request_buffer,
+                       (struct scatterlist *)scsicmd->buffer,
                        scsicmd->use_sg,
                        scsicmd->sc_data_direction);
        else if(scsicmd->request_bufflen)
@@ -1090,7 +1081,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
                
                aac_build_sgraw(scsicmd, &readcmd->sg);
                fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(readcmd->sg.count) - 1) * sizeof (struct sgentryraw));
-               BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
+               if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
+                       BUG();
                /*
                 *      Now send the Fib to the adapter
                 */
@@ -1158,10 +1150,8 @@ static int aac_read(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Check that the command queued to the controller
         */
-       if (status == -EINPROGRESS) {
-               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+       if (status == -EINPROGRESS) 
                return 0;
-       }
                
        printk(KERN_WARNING "aac_read: aac_fib_send failed with status: %d.\n", status);
        /*
@@ -1258,7 +1248,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
                
                aac_build_sgraw(scsicmd, &writecmd->sg);
                fibsize = sizeof(struct aac_raw_io) + ((le32_to_cpu(writecmd->sg.count) - 1) * sizeof (struct sgentryraw));
-               BUG_ON(fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)));
+               if (fibsize > (dev->max_fib_size - sizeof(struct aac_fibhdr)))
+                       BUG();
                /*
                 *      Now send the Fib to the adapter
                 */
@@ -1326,8 +1317,8 @@ static int aac_write(struct scsi_cmnd * scsicmd, int cid)
        /*
         *      Check that the command queued to the controller
         */
-       if (status == -EINPROGRESS) {
-               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+       if (status == -EINPROGRESS)
+       {
                return 0;
        }
 
@@ -1349,7 +1340,6 @@ static void synchronize_callback(void *context, struct fib *fibptr)
        struct scsi_cmnd *cmd;
 
        cmd = context;
-       cmd->SCp.phase = AAC_OWNER_MIDLEVEL;
 
        dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 
                                smp_processor_id(), jiffies));
@@ -1363,7 +1353,7 @@ static void synchronize_callback(void *context, struct fib *fibptr)
        else {
                struct scsi_device *sdev = cmd->device;
                struct aac_dev *dev = (struct aac_dev *)sdev->host->hostdata;
-               u32 cid = sdev_id(sdev);
+               u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun);
                printk(KERN_WARNING 
                     "synchronize_callback: synchronize failed, status = %d\n",
                     le32_to_cpu(synchronizereply->status));
@@ -1395,12 +1385,12 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
        unsigned long flags;
 
        /*
-        * Wait for all outstanding queued commands to complete to this
-        * specific target (block).
+        * Wait for all commands to complete to this specific
+        * target (block).
         */
        spin_lock_irqsave(&sdev->list_lock, flags);
        list_for_each_entry(cmd, &sdev->cmd_list, list)
-               if (cmd != scsicmd && cmd->SCp.phase == AAC_OWNER_FIRMWARE) {
+               if (cmd != scsicmd && cmd->serial_number != 0) {
                        ++active;
                        break;
                }
@@ -1443,10 +1433,8 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
        /*
         *      Check that the command queued to the controller
         */
-       if (status == -EINPROGRESS) {
-               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+       if (status == -EINPROGRESS)
                return 0;
-       }
 
        printk(KERN_WARNING 
                "aac_synchronize: aac_fib_send failed with status: %d.\n", status);
@@ -1469,6 +1457,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
        struct Scsi_Host *host = scsicmd->device->host;
        struct aac_dev *dev = (struct aac_dev *)host->hostdata;
        struct fsa_dev_info *fsa_dev_ptr = dev->fsa_dev;
+       int ret;
        
        /*
         *      If the bus, id or lun is out of range, return fail
@@ -1476,14 +1465,13 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
         *      itself.
         */
        if (scmd_id(scsicmd) != host->this_id) {
-               if ((scmd_channel(scsicmd) == CONTAINER_CHANNEL)) {
-                       if((scmd_id(scsicmd) >= dev->maximum_num_containers) ||
-                                       (scsicmd->device->lun != 0)) {
+               if ((scsicmd->device->channel == CONTAINER_CHANNEL)) {
+                       if( (scsicmd->device->id >= dev->maximum_num_containers) || (scsicmd->device->lun != 0)){ 
                                scsicmd->result = DID_NO_CONNECT << 16;
                                scsicmd->scsi_done(scsicmd);
                                return 0;
                        }
-                       cid = scmd_id(scsicmd);
+                       cid = ID_LUN_TO_CONTAINER(scsicmd->device->id, scsicmd->device->lun);
 
                        /*
                         *      If the target container doesn't exist, it may have
@@ -1559,7 +1547,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
        {
                struct inquiry_data inq_data;
 
-               dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scmd_id(scsicmd)));
+               dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
                memset(&inq_data, 0, sizeof (struct inquiry_data));
 
                inq_data.inqd_ver = 2;  /* claim compliance to SCSI-2 */
@@ -1572,7 +1560,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                 *      see: <vendor>.c i.e. aac.c
                 */
                if (scmd_id(scsicmd) == host->this_id) {
-                       setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
+                       setinqstr(dev, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
                        inq_data.inqd_pdt = INQD_PDT_PROC;      /* Processor device */
                        aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
                        scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
@@ -1609,14 +1597,13 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                cp[11] = 0;
                cp[12] = 0;
                aac_internal_transfer(scsicmd, cp, 0,
-                 min_t(size_t, scsicmd->cmnd[13], sizeof(cp)));
+                 min((unsigned int)scsicmd->cmnd[13], sizeof(cp)));
                if (sizeof(cp) < scsicmd->cmnd[13]) {
                        unsigned int len, offset = sizeof(cp);
 
                        memset(cp, 0, offset);
                        do {
-                               len = min_t(size_t, scsicmd->cmnd[13] - offset,
-                                               sizeof(cp));
+                               len = min(scsicmd->cmnd[13]-offset, sizeof(cp));
                                aac_internal_transfer(scsicmd, cp, offset, len);
                        } while ((offset += len) < scsicmd->cmnd[13]);
                }
@@ -1740,19 +1727,24 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
                         *      containers to /dev/sd device names
                         */
                         
+                       spin_unlock_irq(host->host_lock);
                        if (scsicmd->request->rq_disk)
                                strlcpy(fsa_dev_ptr[cid].devname,
                                scsicmd->request->rq_disk->disk_name,
                                min(sizeof(fsa_dev_ptr[cid].devname),
                                sizeof(scsicmd->request->rq_disk->disk_name) + 1));
-
-                       return aac_read(scsicmd, cid);
+                       ret = aac_read(scsicmd, cid);
+                       spin_lock_irq(host->host_lock);
+                       return ret;
 
                case WRITE_6:
                case WRITE_10:
                case WRITE_12:
                case WRITE_16:
-                       return aac_write(scsicmd, cid);
+                       spin_unlock_irq(host->host_lock);
+                       ret = aac_write(scsicmd, cid);
+                       spin_lock_irq(host->host_lock);
+                       return ret;
 
                case SYNCHRONIZE_CACHE:
                        /* Issue FIB to tell Firmware to flush it's cache */
@@ -1785,7 +1777,7 @@ static int query_disk(struct aac_dev *dev, void __user *arg)
        if (copy_from_user(&qd, arg, sizeof (struct aac_query_disk)))
                return -EFAULT;
        if (qd.cnum == -1)
-               qd.cnum = qd.id;
+               qd.cnum = ID_LUN_TO_CONTAINER(qd.id, qd.lun);
        else if ((qd.bus == -1) && (qd.id == -1) && (qd.lun == -1)) 
        {
                if (qd.cnum < 0 || qd.cnum >= dev->maximum_num_containers)
@@ -1897,10 +1889,10 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
        struct scsi_cmnd *scsicmd;
 
        scsicmd = (struct scsi_cmnd *) context;
-       scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL;
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
 
-       BUG_ON(fibptr == NULL);
+       if (fibptr == NULL)
+               BUG();
 
        srbreply = (struct aac_srb_reply *) fib_data(fibptr);
 
@@ -1914,7 +1906,7 @@ static void aac_srb_callback(void *context, struct fib * fibptr)
 
        if(scsicmd->use_sg)
                pci_unmap_sg(dev->pdev, 
-                       (struct scatterlist *)scsicmd->request_buffer,
+                       (struct scatterlist *)scsicmd->buffer,
                        scsicmd->use_sg,
                        scsicmd->sc_data_direction);
        else if(scsicmd->request_bufflen)
@@ -2075,13 +2067,14 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
        u32 timeout;
 
        dev = (struct aac_dev *)scsicmd->device->host->hostdata;
-       if (scmd_id(scsicmd) >= dev->maximum_num_physicals ||
+       if (scsicmd->device->id >= dev->maximum_num_physicals || 
                        scsicmd->device->lun > 7) {
                scsicmd->result = DID_NO_CONNECT << 16;
                scsicmd->scsi_done(scsicmd);
                return 0;
        }
 
+       dev = (struct aac_dev *)scsicmd->device->host->hostdata;
        switch(scsicmd->sc_data_direction){
        case DMA_TO_DEVICE:
                flag = SRB_DataOut;
@@ -2109,8 +2102,8 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
 
        srbcmd = (struct aac_srb*) fib_data(cmd_fibcontext);
        srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
-       srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scmd_channel(scsicmd)));
-       srbcmd->id   = cpu_to_le32(scmd_id(scsicmd));
+       srbcmd->channel  = cpu_to_le32(aac_logical_to_phys(scsicmd->device->channel));
+       srbcmd->id   = cpu_to_le32(scsicmd->device->id);
        srbcmd->lun      = cpu_to_le32(scsicmd->device->lun);
        srbcmd->flags    = cpu_to_le32(flag);
        timeout = scsicmd->timeout_per_command/HZ;
@@ -2167,8 +2160,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
        /*
         *      Check that the command queued to the controller
         */
-       if (status == -EINPROGRESS) {
-               scsicmd->SCp.phase = AAC_OWNER_FIRMWARE;
+       if (status == -EINPROGRESS){
                return 0;
        }
 
@@ -2199,6 +2191,8 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
                        scsicmd->sc_data_direction);
                psg->count = cpu_to_le32(sg_count);
 
+               byte_count = 0;
+
                for (i = 0; i < sg_count; i++) {
                        psg->sg[i].addr = cpu_to_le32(sg_dma_address(sg));
                        psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
@@ -2219,15 +2213,15 @@ static unsigned long aac_build_sg(struct scsi_cmnd* scsicmd, struct sgmap* psg)
                }
        }
        else if(scsicmd->request_bufflen) {
-               u32 addr;
-               scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
+               dma_addr_t addr; 
+               addr = pci_map_single(dev->pdev,
                                scsicmd->request_buffer,
                                scsicmd->request_bufflen,
                                scsicmd->sc_data_direction);
-               addr = scsicmd->SCp.dma_handle;
                psg->count = cpu_to_le32(1);
                psg->sg[0].addr = cpu_to_le32(addr);
                psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
+               scsicmd->SCp.dma_handle = addr;
                byte_count = scsicmd->request_bufflen;
        }
        return byte_count;
@@ -2254,17 +2248,18 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
 
                sg_count = pci_map_sg(dev->pdev, sg, scsicmd->use_sg,
                        scsicmd->sc_data_direction);
+               psg->count = cpu_to_le32(sg_count);
+
+               byte_count = 0;
 
                for (i = 0; i < sg_count; i++) {
-                       int count = sg_dma_len(sg);
                        addr = sg_dma_address(sg);
                        psg->sg[i].addr[0] = cpu_to_le32(addr & 0xffffffff);
                        psg->sg[i].addr[1] = cpu_to_le32(addr>>32);
-                       psg->sg[i].count = cpu_to_le32(count);
-                       byte_count += count;
+                       psg->sg[i].count = cpu_to_le32(sg_dma_len(sg));
+                       byte_count += sg_dma_len(sg);
                        sg++;
                }
-               psg->count = cpu_to_le32(sg_count);
                /* hba wants the size to be exact */
                if(byte_count > scsicmd->request_bufflen){
                        u32 temp = le32_to_cpu(psg->sg[i-1].count) - 
@@ -2279,15 +2274,16 @@ static unsigned long aac_build_sg64(struct scsi_cmnd* scsicmd, struct sgmap64* p
                }
        }
        else if(scsicmd->request_bufflen) {
-               scsicmd->SCp.dma_handle = pci_map_single(dev->pdev,
+               u64 addr; 
+               addr = pci_map_single(dev->pdev,
                                scsicmd->request_buffer,
                                scsicmd->request_bufflen,
                                scsicmd->sc_data_direction);
-               addr = scsicmd->SCp.dma_handle;
                psg->count = cpu_to_le32(1);
                psg->sg[0].addr[0] = cpu_to_le32(addr & 0xffffffff);
                psg->sg[0].addr[1] = cpu_to_le32(addr >> 32);
                psg->sg[0].count = cpu_to_le32(scsicmd->request_bufflen);  
+               scsicmd->SCp.dma_handle = addr;
                byte_count = scsicmd->request_bufflen;
        }
        return byte_count;
@@ -2376,7 +2372,7 @@ static struct aac_srb_status_info srb_status_info[] = {
        { SRB_STATUS_SUCCESS,           "Success"},
        { SRB_STATUS_ABORTED,           "Aborted Command"},
        { SRB_STATUS_ABORT_FAILED,      "Abort Failed"},
-       { SRB_STATUS_ERROR,             "Error Event"},
+       { SRB_STATUS_ERROR,             "Error Event"}, 
        { SRB_STATUS_BUSY,              "Device Busy"},
        { SRB_STATUS_INVALID_REQUEST,   "Invalid Request"},
        { SRB_STATUS_INVALID_PATH_ID,   "Invalid Path ID"},
@@ -2395,7 +2391,7 @@ static struct aac_srb_status_info srb_status_info[] = {
        { SRB_STATUS_BAD_SRB_BLOCK_LENGTH,"Bad Srb Block Length"},
        { SRB_STATUS_REQUEST_FLUSHED,   "Request Flushed"},
        { SRB_STATUS_DELAYED_RETRY,     "Delayed Retry"},
-       { SRB_STATUS_INVALID_LUN,       "Invalid LUN"},
+       { SRB_STATUS_INVALID_LUN,       "Invalid LUN"}, 
        { SRB_STATUS_INVALID_TARGET_ID, "Invalid TARGET ID"},
        { SRB_STATUS_BAD_FUNCTION,      "Bad Function"},
        { SRB_STATUS_ERROR_RECOVERY,    "Error Recovery"},
@@ -2410,9 +2406,11 @@ char *aac_get_status_string(u32 status)
 {
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(srb_status_info); i++)
-               if (srb_status_info[i].status == status)
+       for(i=0; i < (sizeof(srb_status_info)/sizeof(struct aac_srb_status_info)); i++ ){
+               if(srb_status_info[i].status == status){
                        return srb_status_info[i].str;
+               }
+       }
 
        return "Bad Status Code";
 }