[SCSI] megaraid_sas: Fix the frame count calculation
[safe/jmp/linux-2.6] / drivers / scsi / dpt_i2o.c
index 365db53..c9dd839 100644 (file)
@@ -55,7 +55,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
 #include <linux/sched.h>
 #include <linux/reboot.h>
 #include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 #include <linux/dma-mapping.h>
 
 #include <linux/timer.h>
@@ -116,7 +115,7 @@ static int sys_tbl_len = 0;
 static adpt_hba* hba_chain = NULL;
 static int hba_count = 0;
 
-static struct file_operations adpt_fops = {
+static const struct file_operations adpt_fops = {
        .ioctl          = adpt_ioctl,
        .open           = adpt_open,
        .release        = adpt_close
@@ -195,8 +194,6 @@ static int adpt_detect(struct scsi_host_template* sht)
                        pci_dev_get(pDev);
                }
        }
-       if (pDev)
-               pci_dev_put(pDev);
 
        /* In INIT state, Activate IOPs */
        for (pHba = hba_chain; pHba; pHba = pHba->next) {
@@ -271,7 +268,7 @@ rebuild_sys_tab:
 
 
 /*
- * scsi_unregister will be called AFTER we return. 
+ * scsi_unregister will be called AFTER we return.
  */
 static int adpt_release(struct Scsi_Host *host)
 {
@@ -885,7 +882,7 @@ static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
 #endif
 
 
-static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev) 
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
 {
 
        adpt_hba* pHba = NULL;
@@ -909,8 +906,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
        }
 
        pci_set_master(pDev);
-       if (pci_set_dma_mask(pDev, DMA_64BIT_MASK) &&
-           pci_set_dma_mask(pDev, DMA_32BIT_MASK))
+       if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
                return -EINVAL;
 
        base_addr0_phys = pci_resource_start(pDev,0);
@@ -953,16 +949,14 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
        }
        
        // Allocate and zero the data structure
-       pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
-       if( pHba == NULL) {
-               if(msg_addr_virt != base_addr_virt){
+       pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL);
+       if (!pHba) {
+               if (msg_addr_virt != base_addr_virt)
                        iounmap(msg_addr_virt);
-               }
                iounmap(base_addr_virt);
                pci_release_regions(pDev);
                return -ENOMEM;
        }
-       memset(pHba, 0, sizeof(adpt_hba));
 
        mutex_lock(&adpt_configuration_lock);
 
@@ -1311,13 +1305,12 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                schedule_timeout_uninterruptible(1);
        } while (m == EMPTY_QUEUE);
 
-       status = kmalloc(4, GFP_KERNEL|ADDR32);
+       status = kzalloc(4, GFP_KERNEL|ADDR32);
        if(status == NULL) {
                adpt_send_nop(pHba, m);
                printk(KERN_ERR"IOP reset failed - no free memory.\n");
                return -ENOMEM;
        }
-       memset(status,0,4);
 
        msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
        msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
@@ -1507,21 +1500,19 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
                                        continue;
                                }
                                if( pHba->channel[bus_no].device[scsi_id] == NULL){
-                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       pDev =  kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
                                        if(pDev == NULL) {
                                                return -ENOMEM;
                                        }
                                        pHba->channel[bus_no].device[scsi_id] = pDev;
-                                       memset(pDev,0,sizeof(struct adpt_device));
                                } else {
                                        for( pDev = pHba->channel[bus_no].device[scsi_id];      
                                                        pDev->next_lun; pDev = pDev->next_lun){
                                        }
-                                       pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
                                        if(pDev->next_lun == NULL) {
                                                return -ENOMEM;
                                        }
-                                       memset(pDev->next_lun,0,sizeof(struct adpt_device));
                                        pDev = pDev->next_lun;
                                }
                                pDev->tid = tid;
@@ -1670,12 +1661,11 @@ static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
                reply_size = REPLY_FRAME_SIZE;
        }
        reply_size *= 4;
-       reply = kmalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
+       reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
        if(reply == NULL) {
                printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
                return -ENOMEM;
        }
-       memset(reply,0,REPLY_FRAME_SIZE*4);
        sg_offset = (msg[0]>>4)&0xf;
        msg[2] = 0x40000000; // IOCTL context
        msg[3] = (u32)reply;
@@ -2085,12 +2075,13 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        u32 *lenptr;
        int direction;
        int scsidir;
+       int nseg;
        u32 len;
        u32 reqlen;
        s32 rcode;
 
        memset(msg, 0 , sizeof(msg));
-       len = cmd->request_bufflen;
+       len = scsi_bufflen(cmd);
        direction = 0x00000000; 
        
        scsidir = 0x00000000;                   // DATA NO XFER
@@ -2147,21 +2138,21 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
        lenptr=mptr++;          /* Remember me - fill in when we know */
        reqlen = 14;            // SINGLE SGE
        /* Now fill in the SGList and command */
-       if(cmd->use_sg) {
-               struct scatterlist *sg = (struct scatterlist *)cmd->request_buffer;
-               int sg_count = pci_map_sg(pHba->pDev, sg, cmd->use_sg,
-                               cmd->sc_data_direction);
 
+       nseg = scsi_dma_map(cmd);
+       BUG_ON(nseg < 0);
+       if (nseg) {
+               struct scatterlist *sg;
 
                len = 0;
-               for(i = 0 ; i < sg_count; i++) {
+               scsi_for_each_sg(cmd, sg, nseg, i) {
                        *mptr++ = direction|0x10000000|sg_dma_len(sg);
                        len+=sg_dma_len(sg);
                        *mptr++ = sg_dma_address(sg);
-                       sg++;
+                       /* Make this an end of list */
+                       if (i == nseg - 1)
+                               mptr[-2] = direction|0xD0000000|sg_dma_len(sg);
                }
-               /* Make this an end of list */
-               mptr[-2] = direction|0xD0000000|sg_dma_len(sg-1);
                reqlen = mptr - msg;
                *lenptr = len;
                
@@ -2170,16 +2161,8 @@ static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_d
                                len, cmd->underflow);
                }
        } else {
-               *lenptr = len = cmd->request_bufflen;
-               if(len == 0) {
-                       reqlen = 12;
-               } else {
-                       *mptr++ = 0xD0000000|direction|cmd->request_bufflen;
-                       *mptr++ = pci_map_single(pHba->pDev,
-                               cmd->request_buffer,
-                               cmd->request_bufflen,
-                               cmd->sc_data_direction);
-               }
+               *lenptr = len = 0;
+               reqlen = 12;
        }
        
        /* Stick the headers on */
@@ -2207,7 +2190,7 @@ static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
        pHba->host = host;
 
        host->irq = pHba->pDev->irq;
-       /* no IO ports, so don't have to set host->io_port and 
+       /* no IO ports, so don't have to set host->io_port and
         * host->n_io_port
         */
        host->io_port = 0;
@@ -2239,7 +2222,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
        hba_status = detailed_status >> 8;
 
        // calculate resid for sg 
-       cmd->resid = cmd->request_bufflen - readl(reply+5);
+       scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
 
        pHba = (adpt_hba*) cmd->device->host->hostdata[0];
 
@@ -2313,9 +2296,8 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
 
                // copy over the request sense data if it was a check
                // condition status
-               if(dev_status == 0x02 /*CHECK_CONDITION*/) {
-                       u32 len = sizeof(cmd->sense_buffer);
-                       len = (len > 40) ?  40 : len;
+               if (dev_status == SAM_STAT_CHECK_CONDITION) {
+                       u32 len = min(SCSI_SENSE_BUFFERSIZE, 40);
                        // Copy over the sense data
                        memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
                        if(cmd->sense_buffer[0] == 0x70 /* class 7 */ && 
@@ -2447,7 +2429,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
                                }
                                pDev = pHba->channel[bus_no].device[scsi_id];   
                                if( pDev == NULL){
-                                       pDev =  kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       pDev =  kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
                                        if(pDev == NULL) {
                                                return -ENOMEM;
                                        }
@@ -2456,12 +2438,11 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
                                        while (pDev->next_lun) {
                                                pDev = pDev->next_lun;
                                        }
-                                       pDev = pDev->next_lun = kmalloc(sizeof(struct adpt_device),GFP_KERNEL);
+                                       pDev = pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
                                        if(pDev == NULL) {
                                                return -ENOMEM;
                                        }
                                }
-                               memset(pDev,0,sizeof(struct adpt_device));
                                pDev->tid = d->lct_data.tid;
                                pDev->scsi_channel = bus_no;
                                pDev->scsi_id = scsi_id;
@@ -2682,14 +2663,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 
        msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
 
-       status = kmalloc(4,GFP_KERNEL|ADDR32);
-       if (status==NULL) {
+       status = kzalloc(4, GFP_KERNEL|ADDR32);
+       if (!status) {
                adpt_send_nop(pHba, m);
                printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
                        pHba->name);
                return -ENOMEM;
        }
-       memset(status, 0, 4);
 
        writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
        writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
@@ -2728,12 +2708,11 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 
        kfree(pHba->reply_pool);
 
-       pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
-       if(!pHba->reply_pool){
-               printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
-               return -1;
+       pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+       if (!pHba->reply_pool) {
+               printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
+               return -ENOMEM;
        }
-       memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
 
        ptr = pHba->reply_pool;
        for(i = 0; i < pHba->reply_fifo_size; i++) {
@@ -2944,12 +2923,11 @@ static int adpt_i2o_build_sys_table(void)
 
        kfree(sys_tbl);
 
-       sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
-       if(!sys_tbl) {
+       sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+       if (!sys_tbl) {
                printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");     
                return -ENOMEM;
        }
-       memset(sys_tbl, 0, sys_tbl_len);
 
        sys_tbl->num_entries = hba_count;
        sys_tbl->version = I2OVERSION;
@@ -3348,7 +3326,7 @@ static struct scsi_host_template driver_template = {
        .name                   = "dpt_i2o",
        .proc_name              = "dpt_i2o",
        .proc_info              = adpt_proc_info,
-       .detect                 = adpt_detect,  
+       .detect                 = adpt_detect,
        .release                = adpt_release,
        .info                   = adpt_info,
        .queuecommand           = adpt_queue,