Pull bugzilla-5452 into release branch
[pandora-kernel.git] / drivers / block / cciss.c
index b9c786e..1319d8f 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>
 
@@ -995,13 +996,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 +1180,53 @@ 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 */
+
+       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 +1295,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,
@@ -2137,7 +2185,7 @@ static void start_io( ctlr_info_t *h)
                        break;
                }
 
-               /* Get the frist entry from the Request Q */ 
+               /* Get the first entry from the Request Q */ 
                removeQ(&(h->reqQ), c);
                h->Qdepth--;
        
@@ -2148,20 +2196,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 +2213,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 +2332,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 +2361,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;
@@ -2728,9 +2729,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;
 }
@@ -2939,13 +2940,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 +3059,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;
@@ -3268,8 +3267,8 @@ 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);
 }