[SCSI] libiscsi: use is_power_of_2
[safe/jmp/linux-2.6] / drivers / scsi / dpt_i2o.c
index 6e6b293..b31d1c9 100644 (file)
@@ -46,7 +46,6 @@ MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
 
 #include <linux/stat.h>
 #include <linux/slab.h>                /* for kmalloc() */
-#include <linux/config.h>      /* for CONFIG_PCI */
 #include <linux/pci.h>         /* for PCI support */
 #include <linux/proc_fs.h>
 #include <linux/blkdev.h>
@@ -56,7 +55,7 @@ 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>
 #include <linux/string.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
@@ -184,7 +183,7 @@ static int adpt_detect(struct scsi_host_template* sht)
        PINFO("Detecting Adaptec I2O RAID controllers...\n");
 
         /* search for all Adatpec I2O RAID cards */
-       while ((pDev = pci_find_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
+       while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
                if(pDev->device == PCI_DPT_DEVICE_ID ||
                   pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
                        if(adpt_install_hba(sht, pDev) ){
@@ -192,6 +191,7 @@ static int adpt_detect(struct scsi_host_template* sht)
                                PERROR("Will not try to detect others.\n");
                                return hba_count-1;
                        }
+                       pci_dev_get(pDev);
                }
        }
 
@@ -268,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)
 {
@@ -294,7 +294,7 @@ static void adpt_inquiry(adpt_hba* pHba)
        s32 rcode;
 
        memset(msg, 0, sizeof(msg));
-       buf = (u8*)kmalloc(80,GFP_KERNEL|ADDR32);
+       buf = kmalloc(80,GFP_KERNEL|ADDR32);
        if(!buf){
                printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
                return;
@@ -882,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;
@@ -906,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, 0xffffffffffffffffULL) &&
-           pci_set_dma_mask(pDev, 0xffffffffULL))
+       if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
                return -EINVAL;
 
        base_addr0_phys = pci_resource_start(pDev,0);
@@ -950,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);
 
@@ -1008,7 +1005,7 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
                printk(KERN_INFO"     BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
        }
 
-       if (request_irq (pDev->irq, adpt_isr, SA_SHIRQ, pHba->name, pHba)) {
+       if (request_irq (pDev->irq, adpt_isr, IRQF_SHARED, pHba->name, pHba)) {
                printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
                adpt_i2o_delete_hba(pHba);
                return -EINVAL;
@@ -1075,6 +1072,7 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba)
                        }
                }
        }
+       pci_dev_put(pHba->pDev);
        kfree(pHba);
 
        if(hba_count <= 0){
@@ -1307,13 +1305,12 @@ static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
                schedule_timeout_uninterruptible(1);
        } while (m == EMPTY_QUEUE);
 
-       status = (u8*)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;
@@ -1440,7 +1437,7 @@ static int adpt_i2o_parse_lct(adpt_hba* pHba)
                        }
                        continue;
                }
-               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+               d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
                if(d==NULL)
                {
                        printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
@@ -1503,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;
@@ -1666,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;
@@ -1985,7 +1979,7 @@ static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
 }
 
 
-static irqreturn_t adpt_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t adpt_isr(int irq, void *dev_id)
 {
        struct scsi_cmnd* cmd;
        adpt_hba* pHba = dev_id;
@@ -2081,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
@@ -2143,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;
                
@@ -2166,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 */
@@ -2203,12 +2190,12 @@ 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;
        host->n_io_port = 0;
-                               /* see comments in hosts.h */
+                               /* see comments in scsi_host.h */
        host->max_id = 16;
        host->max_lun = 256;
        host->max_channel = pHba->top_scsi_channel + 1;
@@ -2235,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];
 
@@ -2421,7 +2408,7 @@ static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
                                pDev = pDev->next_lun;
                        }
                        if(!pDev ) { // Something new add it
-                               d = (struct i2o_device *)kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
+                               d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
                                if(d==NULL)
                                {
                                        printk(KERN_CRIT "Out of memory for I2O device data.\n");
@@ -2443,7 +2430,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;
                                        }
@@ -2452,12 +2439,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;
@@ -2678,14 +2664,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]);
@@ -2724,12 +2709,11 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
 
        kfree(pHba->reply_pool);
 
-       pHba->reply_pool = (u32*)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++) {
@@ -2940,12 +2924,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;
@@ -3344,7 +3327,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,
@@ -3358,6 +3341,7 @@ static struct scsi_host_template driver_template = {
        .this_id                = 7,
        .cmd_per_lun            = 1,
        .use_clustering         = ENABLE_CLUSTERING,
+       .use_sg_chaining        = ENABLE_SG_CHAINING,
 };
 #include "scsi_module.c"
 MODULE_LICENSE("GPL");