[PATCH] CCISS: use ARRAY_SIZE without intermediates
[safe/jmp/linux-2.6] / drivers / block / cciss.c
index cf39cf9..94e82a2 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
 #include <linux/compat.h>
+#include <linux/blktrace_api.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -103,8 +104,6 @@ static const struct pci_device_id cciss_pci_device_id[] = {
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
 
-#define NR_PRODUCTS ARRAY_SIZE(products)
-
 /*  board_id = Subsystem Device ID & Vendor ID
  *  product = Marketing Name for the board
  *  access = Address of the struct of function pointers 
@@ -995,13 +994,11 @@ static int cciss_ioctl(struct inode *inode, struct file *filep,
                        status = -EINVAL;
                        goto cleanup1;
                }
-               buff = (unsigned char **) kmalloc(MAXSGENTRIES * 
-                               sizeof(char *), GFP_KERNEL);
+               buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
                if (!buff) {
                        status = -ENOMEM;
                        goto cleanup1;
                }
-               memset(buff, 0, MAXSGENTRIES);
                buff_size = (int *) kmalloc(MAXSGENTRIES * sizeof(int), 
                                        GFP_KERNEL);
                if (!buff_size) {
@@ -1181,6 +1178,54 @@ static int revalidate_allvol(ctlr_info_t *host)
         return 0;
 }
 
+static inline void complete_buffers(struct bio *bio, int status)
+{
+       while (bio) {
+               struct bio *xbh = bio->bi_next;
+               int nr_sectors = bio_sectors(bio);
+
+               bio->bi_next = NULL;
+               blk_finished_io(len);
+               bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO);
+               bio = xbh;
+       }
+
+}
+
+static void cciss_softirq_done(struct request *rq)
+{
+       CommandList_struct *cmd = rq->completion_data;
+       ctlr_info_t *h = hba[cmd->ctlr];
+       unsigned long flags;
+       u64bit temp64;
+       int i, ddir;
+
+       if (cmd->Request.Type.Direction == XFER_READ)
+               ddir = PCI_DMA_FROMDEVICE;
+       else
+               ddir = PCI_DMA_TODEVICE;
+
+       /* command did not need to be retried */
+       /* unmap the DMA mapping for all the scatter gather elements */
+       for(i=0; i<cmd->Header.SGList; i++) {
+               temp64.val32.lower = cmd->SG[i].Addr.lower;
+               temp64.val32.upper = cmd->SG[i].Addr.upper;
+               pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
+       }
+
+       complete_buffers(rq->bio, rq->errors);
+
+#ifdef CCISS_DEBUG
+       printk("Done with %p\n", rq);
+#endif /* CCISS_DEBUG */
+
+       add_disk_randomness(rq->rq_disk);
+       spin_lock_irqsave(&h->lock, flags);
+       end_that_request_last(rq, rq->errors);
+       cmd_free(h, cmd,1);
+       spin_unlock_irqrestore(&h->lock, flags);
+}
+
 /* This function will check the usage_count of the drive to be updated/added.
  * If the usage_count is zero then the drive information will be updated and
  * the disk will be re-registered with the kernel.  If not then it will be
@@ -1249,6 +1294,8 @@ static void cciss_update_drive_info(int ctlr, int drv_index)
 
                blk_queue_max_sectors(disk->queue, 512);
 
+               blk_queue_softirq_done(disk->queue, cciss_softirq_done);
+
                disk->queue->queuedata = hba[ctlr];
 
                blk_queue_hardsect_size(disk->queue,
@@ -2148,20 +2195,6 @@ static void start_io( ctlr_info_t *h)
                addQ (&(h->cmpQ), c); 
        }
 }
-
-static inline void complete_buffers(struct bio *bio, int status)
-{
-       while (bio) {
-               struct bio *xbh = bio->bi_next; 
-               int nr_sectors = bio_sectors(bio);
-
-               bio->bi_next = NULL; 
-               blk_finished_io(len);
-               bio_endio(bio, nr_sectors << 9, status ? 0 : -EIO);
-               bio = xbh;
-       }
-
-} 
 /* Assumes that CCISS_LOCK(h->ctlr) is held. */
 /* Zeros out the error record and then resends the command back */
 /* to the controller */
@@ -2179,39 +2212,6 @@ static inline void resend_cciss_cmd( ctlr_info_t *h, CommandList_struct *c)
        start_io(h);
 }
 
-static void cciss_softirq_done(struct request *rq)
-{
-       CommandList_struct *cmd = rq->completion_data;
-       ctlr_info_t *h = hba[cmd->ctlr];
-       unsigned long flags;
-       u64bit temp64;
-       int i, ddir;
-
-       if (cmd->Request.Type.Direction == XFER_READ)
-               ddir = PCI_DMA_FROMDEVICE;
-       else
-               ddir = PCI_DMA_TODEVICE;
-
-       /* command did not need to be retried */
-       /* unmap the DMA mapping for all the scatter gather elements */
-       for(i=0; i<cmd->Header.SGList; i++) {
-               temp64.val32.lower = cmd->SG[i].Addr.lower;
-               temp64.val32.upper = cmd->SG[i].Addr.upper;
-               pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir);
-       }
-
-       complete_buffers(rq->bio, rq->errors);
-
-#ifdef CCISS_DEBUG
-       printk("Done with %p\n", rq);
-#endif /* CCISS_DEBUG */ 
-
-       spin_lock_irqsave(&h->lock, flags);
-       end_that_request_last(rq, rq->errors);
-       cmd_free(h, cmd,1);
-       spin_unlock_irqrestore(&h->lock, flags);
-}
-
 /* checks the status of the job and calls complete buffers to mark all 
  * buffers for the completed job. Note that this function does not need
  * to hold the hba/queue lock.
@@ -2331,6 +2331,7 @@ static inline void complete_command( ctlr_info_t *h, CommandList_struct *cmd,
 
        cmd->rq->completion_data = cmd;
        cmd->rq->errors = status;
+       blk_add_trace_rq(cmd->rq->q, cmd->rq, BLK_TA_COMPLETE);
        blk_complete_request(cmd->rq);
 }
 
@@ -2359,8 +2360,7 @@ queue:
        if (!creq)
                goto startio;
 
-       if (creq->nr_phys_segments > MAXSGENTRIES)
-                BUG();
+       BUG_ON(creq->nr_phys_segments > MAXSGENTRIES);
 
        if (( c = cmd_alloc(h, 1)) == NULL)
                goto full;
@@ -2636,16 +2636,6 @@ static void print_cfg_table( CfgTable_struct *tb)
 }
 #endif /* CCISS_DEBUG */ 
 
-static void release_io_mem(ctlr_info_t *c)
-{
-       /* if IO mem was not protected do nothing */
-       if( c->io_mem_addr == 0)
-               return;
-       release_region(c->io_mem_addr, c->io_mem_length);
-       c->io_mem_addr = 0;
-       c->io_mem_length = 0;
-}
-
 static int find_PCI_BAR_index(struct pci_dev *pdev,
                                unsigned long pci_bar_addr)
 {
@@ -2728,9 +2718,9 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, struct pci_dev *pdev,
                         return;
                 }
         }
+default_int_mode:
 #endif /* CONFIG_PCI_MSI */
        /* if we get here we're going to use the default interrupt mode */
-default_int_mode:
         c->intr[SIMPLE_MODE_INT] = pdev->irq;
        return;
 }
@@ -2742,7 +2732,7 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        __u64 cfg_offset;
        __u32 cfg_base_addr;
        __u64 cfg_base_addr_index;
-       int i;
+       int i, err;
 
        /* check to see if controller has been disabled */
        /* BEFORE trying to enable it */
@@ -2750,13 +2740,21 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        if(!(command & 0x02))
        {
                printk(KERN_WARNING "cciss: controller appears to be disabled\n");
-               return(-1);
+               return -ENODEV;
        }
 
-       if (pci_enable_device(pdev))
+       err = pci_enable_device(pdev);
+       if (err)
        {
                printk(KERN_ERR "cciss: Unable to Enable PCI device\n");
-               return( -1);
+               return err;
+       }
+
+       err = pci_request_regions(pdev, "cciss");
+       if (err) {
+               printk(KERN_ERR "cciss: Cannot obtain PCI resources, "
+                       "aborting\n");
+               goto err_out_disable_pdev;
        }
 
        subsystem_vendor_id = pdev->subsystem_vendor;
@@ -2764,31 +2762,6 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) |
                                        subsystem_vendor_id);
 
-       /* search for our IO range so we can protect it */
-       for(i=0; i<DEVICE_COUNT_RESOURCE; i++)
-       {
-               /* is this an IO range */ 
-               if( pci_resource_flags(pdev, i) & 0x01 ) {
-                       c->io_mem_addr = pci_resource_start(pdev, i);
-                       c->io_mem_length = pci_resource_end(pdev, i) -
-                               pci_resource_start(pdev, i) +1;
-#ifdef CCISS_DEBUG
-                       printk("IO value found base_addr[%d] %lx %lx\n", i,
-                               c->io_mem_addr, c->io_mem_length);
-#endif /* CCISS_DEBUG */
-                       /* register the IO range */ 
-                       if(!request_region( c->io_mem_addr,
-                                        c->io_mem_length, "cciss"))
-                       {
-                               printk(KERN_WARNING "cciss I/O memory range already in use addr=%lx length=%ld\n",
-                               c->io_mem_addr, c->io_mem_length);
-                               c->io_mem_addr= 0;
-                               c->io_mem_length = 0;
-                       } 
-                       break;
-               }
-       }
-
 #ifdef CCISS_DEBUG
        printk("command = %x\n", command);
        printk("irq = %x\n", pdev->irq);
@@ -2822,7 +2795,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        }
        if (scratchpad != CCISS_FIRMWARE_READY) {
                printk(KERN_WARNING "cciss: Board not ready.  Timed out.\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
        /* get the address index number */
@@ -2838,8 +2812,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
 #endif /* CCISS_DEBUG */
        if (cfg_base_addr_index == -1) {
                printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n");
-               release_io_mem(c);
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
        cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET);
@@ -2855,18 +2829,19 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        print_cfg_table(c->cfgtable);
 #endif /* CCISS_DEBUG */
 
-       for(i=0; i<NR_PRODUCTS; i++) {
+       for(i=0; i<ARRAY_SIZE(products); i++) {
                if (board_id == products[i].board_id) {
                        c->product_name = products[i].product_name;
                        c->access = *(products[i].access);
                        break;
                }
        }
-       if (i == NR_PRODUCTS) {
+       if (i == ARRAY_SIZE(products)) {
                printk(KERN_WARNING "cciss: Sorry, I don't know how"
                        " to access the Smart Array controller %08lx\n", 
                                (unsigned long)board_id);
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
        if (  (readb(&c->cfgtable->Signature[0]) != 'C') ||
              (readb(&c->cfgtable->Signature[1]) != 'I') ||
@@ -2874,7 +2849,8 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
              (readb(&c->cfgtable->Signature[3]) != 'S') )
        {
                printk("Does not appear to be a valid CISS config table\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
 
 #ifdef CONFIG_X86
@@ -2918,10 +2894,17 @@ static int cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev)
        {
                printk(KERN_WARNING "cciss: unable to get board into"
                                        " simple mode\n");
-               return -1;
+               err = -ENODEV;
+               goto err_out_free_res;
        }
        return 0;
 
+err_out_free_res:
+       pci_release_regions(pdev);
+
+err_out_disable_pdev:
+       pci_disable_device(pdev);
+       return err;
 }
 
 /* 
@@ -2939,13 +2922,12 @@ static void cciss_getgeometry(int cntl_num)
        int block_size;
        int total_size; 
 
-       ld_buff = kmalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
+       ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL);
        if (ld_buff == NULL)
        {
                printk(KERN_ERR "cciss: out of memory\n");
                return;
        }
-       memset(ld_buff, 0, sizeof(ReportLunData_struct));
        size_buff = kmalloc(sizeof( ReadCapdata_struct), GFP_KERNEL);
         if (size_buff == NULL)
         {
@@ -3059,10 +3041,9 @@ static int alloc_cciss_hba(void)
        for(i=0; i< MAX_CTLR; i++) {
                if (!hba[i]) {
                        ctlr_info_t *p;
-                       p = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+                       p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL);
                        if (!p)
                                goto Enomem;
-                       memset(p, 0, sizeof(ctlr_info_t));
                        for (n = 0; n < NWD; n++)
                                p->gendisk[n] = disk[n];
                        hba[i] = p;
@@ -3103,11 +3084,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        int i;
        int j;
        int rc;
+       int dac;
 
-       printk(KERN_DEBUG "cciss: Device 0x%x has been found at"
-                       " bus %d dev %d func %d\n",
-               pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
-                       PCI_FUNC(pdev->devfn));
        i = alloc_cciss_hba();
        if(i < 0)
                return (-1);
@@ -3123,11 +3101,11 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 
        /* configure PCI DMA stuff */
        if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK))
-               printk("cciss: using DAC cycles\n");
+               dac = 1;
        else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK))
-               printk("cciss: not using DAC cycles\n");
+               dac = 0;
        else {
-               printk("cciss: no suitable DMA available\n");
+               printk(KERN_ERR "cciss: no suitable DMA available\n");
                goto clean1;
        }
 
@@ -3153,12 +3131,16 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        /* make sure the board interrupts are off */
        hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF);
        if( request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intr,
-               SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, 
-                       hba[i]->devname, hba[i])) {
+               SA_INTERRUPT | SA_SHIRQ, hba[i]->devname, hba[i])) {
                printk(KERN_ERR "cciss: Unable to get irq %d for %s\n",
                        hba[i]->intr[SIMPLE_MODE_INT], hba[i]->devname);
                goto clean2;
        }
+
+       printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
+               hba[i]->devname, pdev->device, pci_name(pdev),
+               hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not");
+
        hba[i]->cmd_pool_bits = kmalloc(((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long), GFP_KERNEL);
        hba[i]->cmd_pool = (CommandList_struct *)pci_alloc_consistent(
                hba[i]->pdev, NR_CMDS * sizeof(CommandList_struct), 
@@ -3238,6 +3220,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
                disk->fops = &cciss_fops;
                disk->queue = q;
                disk->private_data = drv;
+               disk->driverfs_dev = &pdev->dev;
                /* we must register the controller even if no disks exist */
                /* this is for the online array utilities */
                if(!drv->heads && j)
@@ -3267,9 +3250,8 @@ clean4:
 clean2:
        unregister_blkdev(hba[i]->major, hba[i]->devname);
 clean1:
-       release_io_mem(hba[i]);
-       free_hba(i);
        hba[i]->busy_initializing = 0;
+       free_hba(i);
        return(-1);
 }
 
@@ -3313,7 +3295,6 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
                 pci_disable_msi(hba[i]->pdev);
 #endif /* CONFIG_PCI_MSI */
 
-       pci_set_drvdata(pdev, NULL);
        iounmap(hba[i]->vaddr);
        cciss_unregister_scsi(i);  /* unhook from SCSI subsystem */
        unregister_blkdev(hba[i]->major, hba[i]->devname);
@@ -3340,7 +3321,9 @@ static void __devexit cciss_remove_one (struct pci_dev *pdev)
 #ifdef CONFIG_CISS_SCSI_TAPE
        kfree(hba[i]->scsi_rejects.complete);
 #endif
-       release_io_mem(hba[i]);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
        free_hba(i);
 }