X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=blobdiff_plain;f=drivers%2Fblock%2Fcciss.c;h=1319d8f20640505b69ebc6a37c3f9b435910ee0e;hp=b9c786ee6fad21fee1aa32db38369cfc37bd2266;hb=35a5d9ed9fedb74c22cb19ff7d749289473144e0;hpb=d04ef3a795b3b7b376a02713ed5e211e9ae1f917 diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b9c786ee6fad..1319d8f20640 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -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; iHeader.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; iHeader.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); }