From 664a717d3ac5871efc1fd3bb5a32c552dc339d3f Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Jun 2010 12:57:58 -0700 Subject: cciss: enqueue and submit io Clean up some code where we subit our io. The same 5 lines appeared several times. Also helps for a following patch. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 51ceaee98f9..6db790c2802 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -257,6 +257,17 @@ static inline void removeQ(CommandList_struct *c) hlist_del_init(&c->list); } +static void enqueue_cmd_and_start_io(ctlr_info_t *h, + CommandList_struct *c) +{ + unsigned long flags; + spin_lock_irqsave(&h->lock, flags); + addQ(&h->reqQ, c); + h->Qdepth++; + start_io(h); + spin_unlock_irqrestore(&h->lock, flags); +} + static void cciss_free_sg_chain_blocks(SGDescriptor_struct **cmd_sg_list, int nr_cmds) { @@ -1377,7 +1388,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, CommandList_struct *c; char *buff = NULL; u64bit temp64; - unsigned long flags; DECLARE_COMPLETION_ONSTACK(wait); if (!arg) @@ -1449,13 +1459,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } c->waiting = &wait; - /* Put the request on the tail of the request queue */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - addQ(&host->reqQ, c); - host->Qdepth++; - start_io(host); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - + enqueue_cmd_and_start_io(host, c); wait_for_completion(&wait); /* unlock the buffers from DMA */ @@ -1495,7 +1499,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned char **buff = NULL; int *buff_size = NULL; u64bit temp64; - unsigned long flags; BYTE sg_used = 0; int status = 0; int i; @@ -1602,12 +1605,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } } c->waiting = &wait; - /* Put the request on the tail of the request queue */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - addQ(&host->reqQ, c); - host->Qdepth++; - start_io(host); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + enqueue_cmd_and_start_io(host, c); wait_for_completion(&wait); /* unlock the buffers from DMA */ for (i = 0; i < sg_used; i++) { @@ -1729,8 +1727,8 @@ static void cciss_softirq_done(struct request *rq) CommandList_struct *cmd = rq->completion_data; ctlr_info_t *h = hba[cmd->ctlr]; SGDescriptor_struct *curr_sg = cmd->SG; - unsigned long flags; u64bit temp64; + unsigned long flags; int i, ddir; int sg_index = 0; @@ -2679,17 +2677,11 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, { DECLARE_COMPLETION_ONSTACK(wait); u64bit buff_dma_handle; - unsigned long flags; int return_status = IO_OK; resend_cmd2: c->waiting = &wait; - /* Put the request on the tail of the queue and send it */ - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); - addQ(&h->reqQ, c); - h->Qdepth++; - start_io(h); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + enqueue_cmd_and_start_io(h, c); wait_for_completion(&wait); -- cgit v1.2.3-70-g09d2 From 0c2b39087c900bdb240b50ac95ee9da00d844565 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Jun 2010 12:58:00 -0700 Subject: cciss: clean up interrupt handler Simplify the interrupt handler code to more closely match hpsa and to hopefully make it easier to follow. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 236 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 95 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6db790c2802..cae6a138328 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -167,7 +167,8 @@ static DEFINE_MUTEX(scan_mutex); static LIST_HEAD(scan_q); static void do_cciss_request(struct request_queue *q); -static irqreturn_t do_cciss_intr(int irq, void *dev_id); +static irqreturn_t do_cciss_intx(int irq, void *dev_id); +static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); static int cciss_open(struct block_device *bdev, fmode_t mode); static int cciss_release(struct gendisk *disk, fmode_t mode); static int cciss_ioctl(struct block_device *bdev, fmode_t mode, @@ -197,7 +198,6 @@ static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, int attempt_retry); static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c); -static void fail_all_cmds(unsigned long ctlr); static int add_to_scan_list(struct ctlr_info *h); static int scan_thread(void *data); static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c); @@ -3124,6 +3124,34 @@ after_error_processing: blk_complete_request(cmd->rq); } +static inline u32 cciss_tag_contains_index(u32 tag) +{ +#define DIRECT_LOOKUP_BIT 0x04 + return tag & DIRECT_LOOKUP_BIT; +} + +static inline u32 cciss_tag_to_index(u32 tag) +{ +#define DIRECT_LOOKUP_SHIFT 3 + return tag >> DIRECT_LOOKUP_SHIFT; +} + +static inline u32 cciss_tag_discard_error_bits(u32 tag) +{ +#define CCISS_ERROR_BITS 0x03 + return tag & ~CCISS_ERROR_BITS; +} + +static inline void cciss_mark_tag_indexed(u32 *tag) +{ + *tag |= DIRECT_LOOKUP_BIT; +} + +static inline void cciss_set_tag_index(u32 *tag, u32 index) +{ + *tag |= (index << DIRECT_LOOKUP_SHIFT); +} + /* * Get a request and submit it to the controller. */ @@ -3172,8 +3200,8 @@ static void do_cciss_request(struct request_queue *q) /* got command from pool, so use the command block index instead */ /* for direct lookups. */ /* The first 2 bits are reserved for controller error reporting. */ - c->Header.Tag.lower = (c->cmdindex << 3); - c->Header.Tag.lower |= 0x04; /* flag for direct lookup. */ + cciss_set_tag_index(&c->Header.Tag.lower, c->cmdindex); + cciss_mark_tag_indexed(&c->Header.Tag.lower); memcpy(&c->Header.LUN, drv->LunID, sizeof(drv->LunID)); c->Request.CDBLen = 10; /* 12 byte commands not in FW yet; */ c->Request.Type.Type = TYPE_CMD; /* It is a command. */ @@ -3306,15 +3334,73 @@ static inline int interrupt_pending(ctlr_info_t *h) static inline long interrupt_not_for_us(ctlr_info_t *h) { return (((h->access.intr_pending(h) == 0) || - (h->interrupts_enabled == 0))); + (h->interrupts_enabled == 0))); } -static irqreturn_t do_cciss_intr(int irq, void *dev_id) +static inline int bad_tag(ctlr_info_t *h, u32 tag_index, + u32 raw_tag) { - ctlr_info_t *h = dev_id; + if (unlikely(tag_index >= h->nr_cmds)) { + dev_warn(&h->pdev->dev, "bad tag 0x%08x ignored.\n", raw_tag); + return 1; + } + return 0; +} + +static inline void finish_cmd(ctlr_info_t *h, CommandList_struct *c, + u32 raw_tag) +{ + removeQ(c); + if (likely(c->cmd_type == CMD_RWREQ)) + complete_command(h, c, 0); + else if (c->cmd_type == CMD_IOCTL_PEND) + complete(c->waiting); +#ifdef CONFIG_CISS_SCSI_TAPE + else if (c->cmd_type == CMD_SCSI) + complete_scsi_command(c, 0, raw_tag); +#endif +} + +/* process completion of an indexed ("direct lookup") command */ +static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) +{ + u32 tag_index; CommandList_struct *c; + + tag_index = cciss_tag_to_index(raw_tag); + if (bad_tag(h, tag_index, raw_tag)) + return get_next_completion(h); + c = h->cmd_pool + tag_index; + finish_cmd(h, c, raw_tag); + return get_next_completion(h); +} + +/* process completion of a non-indexed command */ +static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag) +{ + u32 tag; + CommandList_struct *c = NULL; + struct hlist_node *tmp; + __u32 busaddr_masked, tag_masked; + + tag = cciss_tag_discard_error_bits(raw_tag); + hlist_for_each_entry(c, tmp, &h->cmpQ, list) { + busaddr_masked = cciss_tag_discard_error_bits(c->busaddr); + tag_masked = cciss_tag_discard_error_bits(tag); + if (busaddr_masked == tag_masked) { + finish_cmd(h, c, raw_tag); + return get_next_completion(h); + } + } + bad_tag(h, h->nr_cmds + 1, raw_tag); + return get_next_completion(h); +} + +static irqreturn_t do_cciss_intx(int irq, void *dev_id) +{ + ctlr_info_t *h = dev_id; unsigned long flags; - __u32 a, a1, a2; + u32 raw_tag; if (interrupt_not_for_us(h)) return IRQ_NONE; @@ -3324,50 +3410,41 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id) */ spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); while (interrupt_pending(h)) { - while ((a = get_next_completion(h)) != FIFO_EMPTY) { - a1 = a; - if ((a & 0x04)) { - a2 = (a >> 3); - if (a2 >= h->nr_cmds) { - printk(KERN_WARNING - "cciss: controller cciss%d failed, stopping.\n", - h->ctlr); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - fail_all_cmds(h->ctlr); - return IRQ_HANDLED; - } + raw_tag = get_next_completion(h); + while (raw_tag != FIFO_EMPTY) { + if (cciss_tag_contains_index(raw_tag)) + raw_tag = process_indexed_cmd(h, raw_tag); + else + raw_tag = process_nonindexed_cmd(h, raw_tag); + } + } - c = h->cmd_pool + a2; - a = c->busaddr; + spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + return IRQ_HANDLED; +} - } else { - struct hlist_node *tmp; +/* Add a second interrupt handler for MSI/MSI-X mode. In this mode we never + * check the interrupt pending register because it is not set. + */ +static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) +{ + ctlr_info_t *h = dev_id; + unsigned long flags; + u32 raw_tag; - a &= ~3; - c = NULL; - hlist_for_each_entry(c, tmp, &h->cmpQ, list) { - if (c->busaddr == a) - break; - } - } - /* - * If we've found the command, take it off the - * completion Q and free it - */ - if (c && c->busaddr == a) { - removeQ(c); - if (c->cmd_type == CMD_RWREQ) { - complete_command(h, c, 0); - } else if (c->cmd_type == CMD_IOCTL_PEND) { - complete(c->waiting); - } -# ifdef CONFIG_CISS_SCSI_TAPE - else if (c->cmd_type == CMD_SCSI) - complete_scsi_command(c, 0, a1); -# endif - continue; - } - } + if (interrupt_not_for_us(h)) + return IRQ_NONE; + /* + * If there are completed commands in the completion queue, + * we had better do something about it. + */ + spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + raw_tag = get_next_completion(h); + while (raw_tag != FIFO_EMPTY) { + if (cciss_tag_contains_index(raw_tag)) + raw_tag = process_indexed_cmd(h, raw_tag); + else + raw_tag = process_nonindexed_cmd(h, raw_tag); } spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); @@ -4230,11 +4307,21 @@ 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, - IRQF_DISABLED | IRQF_SHARED, 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; + if (hba[i]->msi_vector || hba[i]->msix_vector) { + if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], + do_cciss_msix_intr, + IRQF_DISABLED, 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; + } + } else { + if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intx, + IRQF_DISABLED, 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", @@ -4534,46 +4621,5 @@ static void __exit cciss_cleanup(void) bus_unregister(&cciss_bus_type); } -static void fail_all_cmds(unsigned long ctlr) -{ - /* If we get here, the board is apparently dead. */ - ctlr_info_t *h = hba[ctlr]; - CommandList_struct *c; - unsigned long flags; - - printk(KERN_WARNING "cciss%d: controller not responding.\n", h->ctlr); - h->alive = 0; /* the controller apparently died... */ - - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - - pci_disable_device(h->pdev); /* Make sure it is really dead. */ - - /* move everything off the request queue onto the completed queue */ - while (!hlist_empty(&h->reqQ)) { - c = hlist_entry(h->reqQ.first, CommandList_struct, list); - removeQ(c); - h->Qdepth--; - addQ(&h->cmpQ, c); - } - - /* Now, fail everything on the completed queue with a HW error */ - while (!hlist_empty(&h->cmpQ)) { - c = hlist_entry(h->cmpQ.first, CommandList_struct, list); - removeQ(c); - if (c->cmd_type != CMD_MSG_STALE) - c->err_info->CommandStatus = CMD_HARDWARE_ERR; - if (c->cmd_type == CMD_RWREQ) { - complete_command(h, c, 0); - } else if (c->cmd_type == CMD_IOCTL_PEND) - complete(c->waiting); -#ifdef CONFIG_CISS_SCSI_TAPE - else if (c->cmd_type == CMD_SCSI) - complete_scsi_command(c, 0, 0); -#endif - } - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - return; -} - module_init(cciss_init); module_exit(cciss_cleanup); -- cgit v1.2.3-70-g09d2 From 2cf3af1c9ec26f8db3f386e48f9d979ad8bb3eff Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Jun 2010 12:58:02 -0700 Subject: cciss: check for msi in interrupt_not_for_us Check to see if h->msi[x]_vector is set. We need this for a following patch. Without this check we process one interrupt then stop because in msi[x] mode the interrupt pending bit is not set. Not sure why we didn't encounter this before. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index cae6a138328..cd830cb64a5 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3333,8 +3333,9 @@ static inline int interrupt_pending(ctlr_info_t *h) static inline long interrupt_not_for_us(ctlr_info_t *h) { - return (((h->access.intr_pending(h) == 0) || - (h->interrupts_enabled == 0))); + return !(h->msi_vector || h->msix_vector) && + ((h->access.intr_pending(h) == 0) || + (h->interrupts_enabled == 0)); } static inline int bad_tag(ctlr_info_t *h, u32 tag_index, -- cgit v1.2.3-70-g09d2 From 5e216153c34ac21781110795284a784037f808e3 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Jun 2010 12:58:06 -0700 Subject: cciss: add performant mode support for Stars/Sirius Add a mode of controller operation called Performant Mode. Even though cciss has been deprecated in favor of hpsa there are new controllers due out next year that HP must support in older vendor distros. Vendors require all fixes/features be upstream. These new controllers support only 16 commands in simple mode but support up to 1024 in performant mode. This requires us to add this support at this late date. The performant mode transport minimizes host PCI accesses by performinf many completions per read. PCI writes are posted so the host can write then immediately get off the bus not waiting for the writwe to complete to the target. In the context of performant mode the host read out to a controller pulls all posted writes into host memory ensuring the reply queue is coherent. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 267 ++++++++++++++++++++++++++++++++++++--------- drivers/block/cciss.h | 109 +++++++++++++++++- drivers/block/cciss_cmd.h | 34 +++++- drivers/block/cciss_scsi.c | 6 +- 4 files changed, 353 insertions(+), 63 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index cd830cb64a5..08a2e619dc3 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -206,6 +206,11 @@ static void cciss_device_release(struct device *dev); static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); +/* performant mode helper functions */ +static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, + int *bucket_map); +static void cciss_put_controller_into_performant_mode(ctlr_info_t *h); + #ifdef CONFIG_PROC_FS static void cciss_procinit(int i); #else @@ -231,6 +236,16 @@ static const struct block_device_operations cciss_fops = { .revalidate_disk = cciss_revalidate, }; +/* set_performant_mode: Modify the tag for cciss performant + * set bit 0 for pull model, bits 3-1 for block fetch + * register number + */ +static void set_performant_mode(ctlr_info_t *h, CommandList_struct *c) +{ + if (likely(h->transMethod == CFGTBL_Trans_Performant)) + c->busaddr |= 1 | (h->blockFetchTable[c->Header.SGList] << 1); +} + /* * Enqueuing and dequeuing functions for cmdlists. */ @@ -261,6 +276,7 @@ static void enqueue_cmd_and_start_io(ctlr_info_t *h, CommandList_struct *c) { unsigned long flags; + set_performant_mode(h, c); spin_lock_irqsave(&h->lock, flags); addQ(&h->reqQ, c); h->Qdepth++; @@ -350,6 +366,28 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", #ifdef CONFIG_PROC_FS +static inline u32 next_command(ctlr_info_t *h) +{ + u32 a; + + if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) + return h->access.command_completed(h); + + if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { + a = *(h->reply_pool_head); /* Next cmd in ring buffer */ + (h->reply_pool_head)++; + h->commands_outstanding--; + } else { + a = FIFO_EMPTY; + } + /* Check for wraparound */ + if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { + h->reply_pool_head = h->reply_pool; + h->reply_pool_wraparound ^= 1; + } + return a; +} + /* * Report information about this controller. */ @@ -377,7 +415,7 @@ static void cciss_seq_show_header(struct seq_file *seq) h->product_name, (unsigned long)h->board_id, h->firm_ver[0], h->firm_ver[1], h->firm_ver[2], - h->firm_ver[3], (unsigned int)h->intr[SIMPLE_MODE_INT], + h->firm_ver[3], (unsigned int)h->intr[PERF_MODE_INT], h->num_luns, h->Qdepth, h->commands_outstanding, h->maxQsinceinit, h->max_outstanding, h->maxSG); @@ -3126,13 +3164,13 @@ after_error_processing: static inline u32 cciss_tag_contains_index(u32 tag) { -#define DIRECT_LOOKUP_BIT 0x04 +#define DIRECT_LOOKUP_BIT 0x10 return tag & DIRECT_LOOKUP_BIT; } static inline u32 cciss_tag_to_index(u32 tag) { -#define DIRECT_LOOKUP_SHIFT 3 +#define DIRECT_LOOKUP_SHIFT 5 return tag >> DIRECT_LOOKUP_SHIFT; } @@ -3262,9 +3300,12 @@ static void do_cciss_request(struct request_queue *q) blk_rq_sectors(creq), seg, chained); #endif /* CCISS_DEBUG */ - c->Header.SGList = c->Header.SGTotal = seg + chained; - if (seg > h->max_cmd_sgentries) + c->Header.SGTotal = seg + chained; + if (seg <= h->max_cmd_sgentries) + c->Header.SGList = c->Header.SGTotal; + else c->Header.SGList = h->max_cmd_sgentries; + set_performant_mode(h, c); if (likely(blk_fs_request(creq))) { if(h->cciss_read == CCISS_READ_10) { @@ -3370,10 +3411,10 @@ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) tag_index = cciss_tag_to_index(raw_tag); if (bad_tag(h, tag_index, raw_tag)) - return get_next_completion(h); + return next_command(h); c = h->cmd_pool + tag_index; finish_cmd(h, c, raw_tag); - return get_next_completion(h); + return next_command(h); } /* process completion of a non-indexed command */ @@ -3390,11 +3431,11 @@ static inline u32 process_nonindexed_cmd(ctlr_info_t *h, u32 raw_tag) tag_masked = cciss_tag_discard_error_bits(tag); if (busaddr_masked == tag_masked) { finish_cmd(h, c, raw_tag); - return get_next_completion(h); + return next_command(h); } } bad_tag(h, h->nr_cmds + 1, raw_tag); - return get_next_completion(h); + return next_command(h); } static irqreturn_t do_cciss_intx(int irq, void *dev_id) @@ -3700,6 +3741,155 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) return -1; } +/* Fill in bucket_map[], given nsgs (the max number of + * scatter gather elements supported) and bucket[], + * which is an array of 8 integers. The bucket[] array + * contains 8 different DMA transfer sizes (in 16 + * byte increments) which the controller uses to fetch + * commands. This function fills in bucket_map[], which + * maps a given number of scatter gather elements to one of + * the 8 DMA transfer sizes. The point of it is to allow the + * controller to only do as much DMA as needed to fetch the + * command, with the DMA transfer size encoded in the lower + * bits of the command address. + */ +static void calc_bucket_map(int bucket[], int num_buckets, + int nsgs, int *bucket_map) +{ + int i, j, b, size; + + /* even a command with 0 SGs requires 4 blocks */ +#define MINIMUM_TRANSFER_BLOCKS 4 +#define NUM_BUCKETS 8 + /* Note, bucket_map must have nsgs+1 entries. */ + for (i = 0; i <= nsgs; i++) { + /* Compute size of a command with i SG entries */ + size = i + MINIMUM_TRANSFER_BLOCKS; + b = num_buckets; /* Assume the biggest bucket */ + /* Find the bucket that is just big enough */ + for (j = 0; j < 8; j++) { + if (bucket[j] >= size) { + b = j; + break; + } + } + /* for a command with i SG entries, use bucket b. */ + bucket_map[i] = b; + } +} + +static void +cciss_put_controller_into_performant_mode(ctlr_info_t *h) +{ + int l = 0; + __u32 trans_support; + __u32 trans_offset; + /* + * 5 = 1 s/g entry or 4k + * 6 = 2 s/g entry or 8k + * 8 = 4 s/g entry or 16k + * 10 = 6 s/g entry or 24k + */ + int bft[8] = { 5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4}; + unsigned long register_value; + + BUILD_BUG_ON(28 > MAXSGENTRIES + 4); + + /* Attempt to put controller into performant mode if supported */ + /* Does board support performant mode? */ + trans_support = readl(&(h->cfgtable->TransportSupport)); + if (!(trans_support & PERFORMANT_MODE)) + return; + + printk(KERN_WARNING "cciss%d: Placing controller into " + "performant mode\n", h->ctlr); + /* Performant mode demands commands on a 32 byte boundary + * pci_alloc_consistent aligns on page boundarys already. + * Just need to check if divisible by 32 + */ + if ((sizeof(CommandList_struct) % 32) != 0) { + printk(KERN_WARNING "%s %d %s\n", + "cciss info: command size[", + (int)sizeof(CommandList_struct), + "] not divisible by 32, no performant mode..\n"); + return; + } + + /* Performant mode ring buffer and supporting data structures */ + h->reply_pool = (__u64 *)pci_alloc_consistent( + h->pdev, h->max_commands * sizeof(__u64), + &(h->reply_pool_dhandle)); + + /* Need a block fetch table for performant mode */ + h->blockFetchTable = kmalloc(((h->maxsgentries+1) * + sizeof(__u32)), GFP_KERNEL); + + if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) + goto clean_up; + + h->reply_pool_wraparound = 1; /* spec: init to 1 */ + + /* Controller spec: zero out this buffer. */ + memset(h->reply_pool, 0, h->max_commands * sizeof(__u64)); + h->reply_pool_head = h->reply_pool; + + trans_offset = readl(&(h->cfgtable->TransMethodOffset)); + calc_bucket_map(bft, ARRAY_SIZE(bft), h->maxsgentries, + h->blockFetchTable); + writel(bft[0], &h->transtable->BlockFetch0); + writel(bft[1], &h->transtable->BlockFetch1); + writel(bft[2], &h->transtable->BlockFetch2); + writel(bft[3], &h->transtable->BlockFetch3); + writel(bft[4], &h->transtable->BlockFetch4); + writel(bft[5], &h->transtable->BlockFetch5); + writel(bft[6], &h->transtable->BlockFetch6); + writel(bft[7], &h->transtable->BlockFetch7); + + /* size of controller ring buffer */ + writel(h->max_commands, &h->transtable->RepQSize); + writel(1, &h->transtable->RepQCount); + writel(0, &h->transtable->RepQCtrAddrLow32); + writel(0, &h->transtable->RepQCtrAddrHigh32); + writel(h->reply_pool_dhandle, &h->transtable->RepQAddr0Low32); + writel(0, &h->transtable->RepQAddr0High32); + writel(CFGTBL_Trans_Performant, + &(h->cfgtable->HostWrite.TransportRequest)); + + h->transMethod = CFGTBL_Trans_Performant; + writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); + /* under certain very rare conditions, this can take awhile. + * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right + * as we enter this code.) */ + for (l = 0; l < MAX_CONFIG_WAIT; l++) { + register_value = readl(h->vaddr + SA5_DOORBELL); + if (!(register_value & CFGTBL_ChangeReq)) + break; + /* delay and try again */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(10); + } + register_value = readl(&(h->cfgtable->TransportActive)); + if (!(register_value & CFGTBL_Trans_Performant)) { + printk(KERN_WARNING "cciss: unable to get board into" + " performant mode\n"); + return; + } + + /* Change the access methods to the performant access methods */ + h->access = SA5_performant_access; + + return; +clean_up: + kfree(h->blockFetchTable); + if (h->reply_pool) + pci_free_consistent(h->pdev, + h->max_commands * sizeof(__u64), + h->reply_pool, + h->reply_pool_dhandle); + return; + +} /* cciss_put_controller_into_performant_mode */ + /* If MSI/MSI-X is supported by the kernel we will try to enable it on * controllers that are capable. If not, we use IO-APIC mode. */ @@ -3749,7 +3939,7 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, default_int_mode: #endif /* CONFIG_PCI_MSI */ /* if we get here we're going to use the default interrupt mode */ - c->intr[SIMPLE_MODE_INT] = pdev->irq; + c->intr[PERF_MODE_INT] = pdev->irq; return; } @@ -3761,6 +3951,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) __u32 cfg_base_addr; __u64 cfg_base_addr_index; int i, prod_index, err; + __u32 trans_offset; subsystem_vendor_id = pdev->subsystem_vendor; subsystem_device_id = pdev->subsystem_device; @@ -3874,11 +4065,16 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) c->cfgtable = remap_pci_mem(pci_resource_start(pdev, cfg_base_addr_index) + cfg_offset, sizeof(CfgTable_struct)); + /* Find performant mode table. */ + trans_offset = readl(&(c->cfgtable->TransMethodOffset)); + c->transtable = remap_pci_mem(pci_resource_start(pdev, + cfg_base_addr_index) + cfg_offset+trans_offset, + sizeof(*c->transtable)); c->board_id = board_id; -#ifdef CCISS_DEBUG - print_cfg_table(c->cfgtable); -#endif /* CCISS_DEBUG */ + #ifdef CCISS_DEBUG + print_cfg_table(c->cfgtable); + #endif /* CCISS_DEBUG */ /* Some controllers support Zero Memory Raid (ZMR). * When configured in ZMR mode the number of supported @@ -3888,7 +4084,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) * are supported on the controller then subtract 4 to * leave a little room for ioctl calls. */ - c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); + c->max_commands = readl(&(c->cfgtable->MaxPerformantModeCommands)); c->maxsgentries = readl(&(c->cfgtable->MaxSGElements)); /* @@ -3933,7 +4129,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) * kernels revealed a bug in the refetch if dom0 resides on a P600. */ if(board_id == 0x3225103C) { - __u32 dma_prefetch; + __u32 dma_prefetch; __u32 dma_refetch; dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); dma_prefetch |= 0x8000; @@ -3944,38 +4140,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) } #ifdef CCISS_DEBUG - printk("Trying to put board into Simple mode\n"); + printk(KERN_WARNING "Trying to put board into Performant mode\n"); #endif /* CCISS_DEBUG */ - c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); - /* Update the field, and then ring the doorbell */ - writel(CFGTBL_Trans_Simple, &(c->cfgtable->HostWrite.TransportRequest)); - writel(CFGTBL_ChangeReq, c->vaddr + SA5_DOORBELL); - - /* under certain very rare conditions, this can take awhile. - * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right - * as we enter this code.) */ - for (i = 0; i < MAX_CONFIG_WAIT; i++) { - if (!(readl(c->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) - break; - /* delay and try again */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(1)); - } - -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "I counter got to %d %x\n", i, - readl(c->vaddr + SA5_DOORBELL)); -#endif /* CCISS_DEBUG */ -#ifdef CCISS_DEBUG - print_cfg_table(c->cfgtable); -#endif /* CCISS_DEBUG */ - - if (!(readl(&(c->cfgtable->TransportActive)) & CFGTBL_Trans_Simple)) { - printk(KERN_WARNING "cciss: unable to get board into" - " simple mode\n"); - err = -ENODEV; - goto err_out_free_res; - } return 0; err_out_free_res: @@ -3984,6 +4150,7 @@ err_out_free_res: * Smart Array controllers that pci_enable_device does not undo */ pci_release_regions(pdev); + cciss_put_controller_into_performant_mode(c); return err; } @@ -4260,7 +4427,6 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, i = alloc_cciss_hba(); if (i < 0) return -1; - hba[i]->busy_initializing = 1; INIT_HLIST_HEAD(&hba[i]->cmpQ); INIT_HLIST_HEAD(&hba[i]->reqQ); @@ -4327,7 +4493,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, 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]->intr[PERF_MODE_INT], dac ? "" : " not"); hba[i]->cmd_pool_bits = kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) @@ -4433,7 +4599,7 @@ clean4: hba[i]->nr_cmds * sizeof(ErrorInfo_struct), hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); - free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); + free_irq(hba[i]->intr[PERF_MODE_INT], hba[i]); clean2: unregister_blkdev(hba[i]->major, hba[i]->devname); clean1: @@ -4475,7 +4641,7 @@ static void cciss_shutdown(struct pci_dev *pdev) printk(KERN_WARNING "cciss%d: Error flushing cache\n", h->ctlr); h->access.set_intr_mask(h, CCISS_INTR_OFF); - free_irq(h->intr[2], h); + free_irq(h->intr[PERF_MODE_INT], h); } static void __devexit cciss_remove_one(struct pci_dev *pdev) @@ -4575,7 +4741,6 @@ static int __init cciss_init(void) * array of them, the size must be a multiple of 8 bytes. */ BUILD_BUG_ON(sizeof(CommandList_struct) % COMMANDLIST_ALIGNMENT); - printk(KERN_INFO DRIVER_NAME "\n"); err = bus_register(&cciss_bus_type); diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c527932d223..8a9f5b58daa 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -85,8 +85,8 @@ struct ctlr_info int max_cmd_sgentries; SGDescriptor_struct **cmd_sg_list; -# define DOORBELL_INT 0 -# define PERF_MODE_INT 1 +# define PERF_MODE_INT 0 +# define DOORBELL_INT 1 # define SIMPLE_MODE_INT 2 # define MEMQ_MODE_INT 3 unsigned int intr[4]; @@ -137,10 +137,27 @@ struct ctlr_info struct list_head scan_list; struct completion scan_wait; struct device dev; + /* + * Performant mode tables. + */ + u32 trans_support; + u32 trans_offset; + struct TransTable_struct *transtable; + unsigned long transMethod; + + /* + * Performant mode completion buffer + */ + u64 *reply_pool; + dma_addr_t reply_pool_dhandle; + u64 *reply_pool_head; + size_t reply_pool_size; + unsigned char reply_pool_wraparound; + u32 *blockFetchTable; }; -/* Defining the diffent access_menthods */ -/* +/* Defining the diffent access_methods + * * Memory mapped FIFO interface (SMART 53xx cards) */ #define SA5_DOORBELL 0x20 @@ -159,6 +176,15 @@ struct ctlr_info #define SA5B_INTR_PENDING 0x04 #define FIFO_EMPTY 0xffffffff #define CCISS_FIRMWARE_READY 0xffff0000 /* value in scratchpad register */ +/* Perf. mode flags */ +#define SA5_PERF_INTR_PENDING 0x04 +#define SA5_PERF_INTR_OFF 0x05 +#define SA5_OUTDB_STATUS_PERF_BIT 0x01 +#define SA5_OUTDB_CLEAR_PERF_BIT 0x01 +#define SA5_OUTDB_CLEAR 0xA0 +#define SA5_OUTDB_CLEAR_PERF_BIT 0x01 +#define SA5_OUTDB_STATUS 0x9C + #define CISS_ERROR_BIT 0x02 @@ -170,8 +196,9 @@ struct ctlr_info static void SA5_submit_command( ctlr_info_t *h, CommandList_struct *c) { #ifdef CCISS_DEBUG - printk("Sending %x - down to controller\n", c->busaddr ); -#endif /* CCISS_DEBUG */ + printk(KERN_WARNING "cciss%d: Sending %08x - down to controller\n", + h->ctlr, c->busaddr); +#endif /* CCISS_DEBUG */ writel(c->busaddr, h->vaddr + SA5_REQUEST_PORT_OFFSET); h->commands_outstanding++; if ( h->commands_outstanding > h->max_outstanding) @@ -214,6 +241,20 @@ static void SA5B_intr_mask(ctlr_info_t *h, unsigned long val) h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); } } + +/* Performant mode intr_mask */ +static void SA5_performant_intr_mask(ctlr_info_t *h, unsigned long val) +{ + if (val) { /* turn on interrupts */ + h->interrupts_enabled = 1; + writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } else { + h->interrupts_enabled = 0; + writel(SA5_PERF_INTR_OFF, + h->vaddr + SA5_REPLY_INTR_MASK_OFFSET); + } +} + /* * Returns true if fifo is full. * @@ -250,6 +291,40 @@ static unsigned long SA5_completed(ctlr_info_t *h) return ( register_value); } + +/* Performant mode command completed */ +static unsigned long SA5_performant_completed(ctlr_info_t *h) +{ + unsigned long register_value = FIFO_EMPTY; + + /* flush the controller write of the reply queue by reading + * outbound doorbell status register. + */ + register_value = readl(h->vaddr + SA5_OUTDB_STATUS); + /* msi auto clears the interrupt pending bit. */ + if (!(h->msi_vector || h->msix_vector)) { + writel(SA5_OUTDB_CLEAR_PERF_BIT, h->vaddr + SA5_OUTDB_CLEAR); + /* Do a read in order to flush the write to the controller + * (as per spec.) + */ + register_value = readl(h->vaddr + SA5_OUTDB_STATUS); + } + + if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { + register_value = *(h->reply_pool_head); + (h->reply_pool_head)++; + h->commands_outstanding--; + } else { + register_value = FIFO_EMPTY; + } + /* Check for wraparound */ + if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { + h->reply_pool_head = h->reply_pool; + h->reply_pool_wraparound ^= 1; + } + + return register_value; +} /* * Returns true if an interrupt is pending.. */ @@ -280,6 +355,20 @@ static bool SA5B_intr_pending(ctlr_info_t *h) return 0 ; } +static bool SA5_performant_intr_pending(ctlr_info_t *h) +{ + unsigned long register_value = readl(h->vaddr + SA5_INTR_STATUS); + + if (!register_value) + return false; + + if (h->msi_vector || h->msix_vector) + return true; + + /* Read outbound doorbell to flush */ + register_value = readl(h->vaddr + SA5_OUTDB_STATUS); + return register_value & SA5_OUTDB_STATUS_PERF_BIT; +} static struct access_method SA5_access = { SA5_submit_command, @@ -297,6 +386,14 @@ static struct access_method SA5B_access = { SA5_completed, }; +static struct access_method SA5_performant_access = { + SA5_submit_command, + SA5_performant_intr_mask, + SA5_fifo_full, + SA5_performant_intr_pending, + SA5_performant_completed, +}; + struct board_type { __u32 board_id; char *product_name; diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index e624ff959cb..eda6a8e6b60 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -54,6 +54,7 @@ #define CFGTBL_AccCmds 0x00000001l #define CFGTBL_Trans_Simple 0x00000002l +#define CFGTBL_Trans_Performant 0x00000004l #define CFGTBL_BusType_Ultra2 0x00000001l #define CFGTBL_BusType_Ultra3 0x00000002l @@ -173,12 +174,15 @@ typedef struct _SGDescriptor_struct { * PAD_64 can be adjusted independently as needed for 32-bit * and 64-bits systems. */ -#define COMMANDLIST_ALIGNMENT (8) +#define COMMANDLIST_ALIGNMENT (32) #define IS_64_BIT ((sizeof(long) - 4)/4) #define IS_32_BIT (!IS_64_BIT) -#define PAD_32 (0) +#define PAD_32 (32) #define PAD_64 (4) #define PADSIZE (IS_32_BIT * PAD_32 + IS_64_BIT * PAD_64) +#define DIRECT_LOOKUP_BIT 0x10 +#define DIRECT_LOOKUP_SHIFT 5 + typedef struct _CommandList_struct { CommandListHeader_struct Header; RequestBlock_struct Request; @@ -195,7 +199,7 @@ typedef struct _CommandList_struct { struct completion *waiting; int retry_count; void * scsi_cmd; - char pad[PADSIZE]; + char pad[PADSIZE]; } CommandList_struct; /* Configuration Table Structure */ @@ -209,12 +213,15 @@ typedef struct _HostWrite_struct { typedef struct _CfgTable_struct { BYTE Signature[4]; DWORD SpecValence; +#define SIMPLE_MODE 0x02 +#define PERFORMANT_MODE 0x04 +#define MEMQ_MODE 0x08 DWORD TransportSupport; DWORD TransportActive; HostWrite_struct HostWrite; DWORD CmdsOutMax; DWORD BusTypes; - DWORD Reserved; + DWORD TransMethodOffset; BYTE ServerName[16]; DWORD HeartBeat; DWORD SCSI_Prefetch; @@ -222,6 +229,25 @@ typedef struct _CfgTable_struct { DWORD MaxLogicalUnits; DWORD MaxPhysicalDrives; DWORD MaxPhysicalDrivesPerLogicalUnit; + DWORD MaxPerformantModeCommands; } CfgTable_struct; + +struct TransTable_struct { + u32 BlockFetch0; + u32 BlockFetch1; + u32 BlockFetch2; + u32 BlockFetch3; + u32 BlockFetch4; + u32 BlockFetch5; + u32 BlockFetch6; + u32 BlockFetch7; + u32 RepQSize; + u32 RepQCount; + u32 RepQCtrAddrLow32; + u32 RepQCtrAddrHigh32; + u32 RepQAddr0Low32; + u32 RepQAddr0High32; +}; + #pragma pack() #endif /* CCISS_CMD_H */ diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 72dae92f3ca..48be4785373 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -93,8 +93,8 @@ static struct scsi_host_template cciss_driver_template = { #pragma pack(1) -#define SCSI_PAD_32 0 -#define SCSI_PAD_64 0 +#define SCSI_PAD_32 8 +#define SCSI_PAD_64 8 struct cciss_scsi_cmd_stack_elem_t { CommandList_struct cmd; @@ -213,6 +213,8 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) /* Check alignment, see cciss_cmd.h near CommandList_struct def. */ BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0); + /* printk(KERN_WARNING "cciss_scsi.c: 0x%08x 0x%08x 0x%08x\n", + 0xdeadbeef, sizeof(*stk->pool), 0xbeefdead); */ /* pci_alloc_consistent guarantees 32-bit DMA address will be used */ stk->pool = (struct cciss_scsi_cmd_stack_elem_t *) pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); -- cgit v1.2.3-70-g09d2 From 841fdffdd382722d33579a6aa1487e8a4e526dbd Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Wed, 2 Jun 2010 12:58:09 -0700 Subject: cciss: new controller support and bump driver version Add support for new controllers due out next year. HP must continue to support new controllers in older distros. All vendors require support be upstream. These controllers support only 16 commands in simple mode but can support up to 1024 in performant mode. See patch 5/6/ We have no marketing names yet. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 08a2e619dc3..5e215ff0a6b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -56,16 +56,14 @@ #include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "HP CISS Driver (v 3.6.20)" -#define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20) +#define DRIVER_NAME "HP CISS Driver (v 3.6.26)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 26) /* Embedded module documentation macros - see modules.h */ MODULE_AUTHOR("Hewlett-Packard Company"); MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); -MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" - " SA6i P600 P800 P400 P400i E200 E200i E500 P700m" - " Smart Array G2 Series SAS/SATA Controllers"); -MODULE_VERSION("3.6.20"); +MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers"); +MODULE_VERSION("3.6.26"); MODULE_LICENSE("GPL"); static int cciss_allow_hpsa; @@ -107,6 +105,11 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324A}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x324B}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3250}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3251}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, + {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, {0,} }; @@ -146,6 +149,11 @@ static struct board_type products[] = { {0x3249103C, "Smart Array P812", &SA5_access}, {0x324A103C, "Smart Array P712m", &SA5_access}, {0x324B103C, "Smart Array P711m", &SA5_access}, + {0x3250103C, "Smart Array", &SA5_access}, + {0x3251103C, "Smart Array", &SA5_access}, + {0x3252103C, "Smart Array", &SA5_access}, + {0x3253103C, "Smart Array", &SA5_access}, + {0x3254103C, "Smart Array", &SA5_access}, }; /* How long to wait (in milliseconds) for board to go into simple mode */ -- cgit v1.2.3-70-g09d2 From 256aea3fd3b5c43e8d05ce66eaf43def83773612 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 11 Jun 2010 13:13:14 +0200 Subject: cciss: make sure we request the performant mode irq Make sure we register the performant mode interrupt Another blunder. Seemed to work because the call to put_controller_into_performant_mode was never called. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 5e215ff0a6b..4f59f03f91f 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4483,18 +4483,18 @@ 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 (hba[i]->msi_vector || hba[i]->msix_vector) { - if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], + if (request_irq(hba[i]->intr[PERF_MODE_INT], do_cciss_msix_intr, IRQF_DISABLED, 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); + hba[i]->intr[PERF_MODE_INT], hba[i]->devname); goto clean2; } } else { - if (request_irq(hba[i]->intr[SIMPLE_MODE_INT], do_cciss_intx, + if (request_irq(hba[i]->intr[PERF_MODE_INT], do_cciss_intx, IRQF_DISABLED, 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); + hba[i]->intr[PERF_MODE_INT], hba[i]->devname); goto clean2; } } -- cgit v1.2.3-70-g09d2 From b14aa6dcd083ad00fb416a93f76131734e6c3c17 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 11 Jun 2010 13:13:35 +0200 Subject: cciss: fix call to put_controller_in_performant_mode call to put_controller_in_performant_mode was in the wrong place The call inadvertently ended up in an error path. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 4f59f03f91f..156ea365c14 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4150,6 +4150,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) #ifdef CCISS_DEBUG printk(KERN_WARNING "Trying to put board into Performant mode\n"); #endif /* CCISS_DEBUG */ + cciss_put_controller_into_performant_mode(c); return 0; err_out_free_res: @@ -4158,7 +4159,6 @@ err_out_free_res: * Smart Array controllers that pci_enable_device does not undo */ pci_release_regions(pdev); - cciss_put_controller_into_performant_mode(c); return err; } -- cgit v1.2.3-70-g09d2 From 29979a71227c46b2ed970b9d603d529c718e5fc8 Mon Sep 17 00:00:00 2001 From: Mike Miller Date: Fri, 11 Jun 2010 13:13:35 +0200 Subject: cciss: move next_command function from ifdef The definition of next_command also ended up in wrong place It ended up inside an "#ifdef CONFIG_PROCFS". Already caught by Randy Dunlap and a couple others. Tried to put it somewhere that made sense. Signed-off-by: Mike Miller Cc: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 156ea365c14..10a0268a1f9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -213,6 +213,7 @@ static void cciss_hba_release(struct device *dev); static void cciss_device_release(struct device *dev); static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); +static inline u32 next_command(ctlr_info_t *h); /* performant mode helper functions */ static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, @@ -374,28 +375,6 @@ static const char *raid_label[] = { "0", "4", "1(1+0)", "5", "5+1", "ADG", #ifdef CONFIG_PROC_FS -static inline u32 next_command(ctlr_info_t *h) -{ - u32 a; - - if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) - return h->access.command_completed(h); - - if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { - a = *(h->reply_pool_head); /* Next cmd in ring buffer */ - (h->reply_pool_head)++; - h->commands_outstanding--; - } else { - a = FIFO_EMPTY; - } - /* Check for wraparound */ - if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { - h->reply_pool_head = h->reply_pool; - h->reply_pool_wraparound ^= 1; - } - return a; -} - /* * Report information about this controller. */ @@ -3411,6 +3390,28 @@ static inline void finish_cmd(ctlr_info_t *h, CommandList_struct *c, #endif } +static inline u32 next_command(ctlr_info_t *h) +{ + u32 a; + + if (unlikely(h->transMethod != CFGTBL_Trans_Performant)) + return h->access.command_completed(h); + + if ((*(h->reply_pool_head) & 1) == (h->reply_pool_wraparound)) { + a = *(h->reply_pool_head); /* Next cmd in ring buffer */ + (h->reply_pool_head)++; + h->commands_outstanding--; + } else { + a = FIFO_EMPTY; + } + /* Check for wraparound */ + if (h->reply_pool_head == (h->reply_pool + h->max_commands)) { + h->reply_pool_head = h->reply_pool; + h->reply_pool_wraparound ^= 1; + } + return a; +} + /* process completion of an indexed ("direct lookup") command */ static inline u32 process_indexed_cmd(ctlr_info_t *h, u32 raw_tag) { -- cgit v1.2.3-70-g09d2 From 33659ebbae262228eef4e0fe990f393d1f0ed941 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 7 Aug 2010 18:17:56 +0200 Subject: block: remove wrappers for request type/flags Remove all the trivial wrappers for the cmd_type and cmd_flags fields in struct requests. This allows much easier grepping for different request types instead of unwinding through macros. Signed-off-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/blk-barrier.c | 7 ++-- block/blk-core.c | 13 ++++---- block/blk-exec.c | 2 +- block/blk-merge.c | 4 +-- block/blk.h | 6 ++-- block/cfq-iosched.c | 19 ++++++----- block/elevator.c | 16 +++++---- drivers/ata/libata-scsi.c | 2 +- drivers/block/cciss.c | 49 ++++++++++++++++----------- drivers/block/hd.c | 2 +- drivers/block/mg_disk.c | 4 +-- drivers/block/nbd.c | 2 +- drivers/block/osdblk.c | 3 +- drivers/block/paride/pd.c | 2 +- drivers/block/ps3disk.c | 2 +- drivers/block/ub.c | 8 ++--- drivers/block/viodasd.c | 2 +- drivers/block/virtio_blk.c | 15 +++++---- drivers/block/xd.c | 2 +- drivers/block/xen-blkfront.c | 4 +-- drivers/block/xsysace.c | 2 +- drivers/cdrom/gdrom.c | 2 +- drivers/cdrom/viocd.c | 2 +- drivers/ide/ide-atapi.c | 17 ++++++---- drivers/ide/ide-cd.c | 66 ++++++++++++++++++++----------------- drivers/ide/ide-disk.c | 2 +- drivers/ide/ide-eh.c | 5 +-- drivers/ide/ide-floppy.c | 25 +++++++++----- drivers/ide/ide-io.c | 8 ++--- drivers/ide/ide-pm.c | 8 ++--- drivers/ide/ide-tape.c | 3 +- drivers/md/dm.c | 10 +++--- drivers/memstick/core/mspro_block.c | 3 +- drivers/message/i2o/i2o_block.c | 2 +- drivers/mmc/card/queue.c | 2 +- drivers/mtd/mtd_blkdevs.c | 4 +-- drivers/scsi/scsi_error.c | 10 +++--- drivers/scsi/scsi_lib.c | 5 +-- drivers/scsi/sd.c | 12 +++---- drivers/scsi/sun3_NCR5380.c | 2 +- drivers/scsi/sun3_scsi.c | 2 +- drivers/scsi/sun3_scsi_vme.c | 2 +- drivers/staging/hv/blkvsc_drv.c | 8 +++-- include/linux/blkdev.h | 41 ++++++++--------------- include/linux/blktrace_api.h | 2 +- include/trace/events/block.h | 15 ++++++--- kernel/trace/blktrace.c | 10 +++--- 47 files changed, 236 insertions(+), 198 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/block/blk-barrier.c b/block/blk-barrier.c index 0d710c9d403..74e40439317 100644 --- a/block/blk-barrier.c +++ b/block/blk-barrier.c @@ -79,7 +79,7 @@ unsigned blk_ordered_req_seq(struct request *rq) * * http://thread.gmane.org/gmane.linux.kernel/537473 */ - if (!blk_fs_request(rq)) + if (rq->cmd_type != REQ_TYPE_FS) return QUEUE_ORDSEQ_DRAIN; if ((rq->cmd_flags & REQ_ORDERED_COLOR) == @@ -236,7 +236,8 @@ static inline bool start_ordered(struct request_queue *q, struct request **rqp) bool blk_do_ordered(struct request_queue *q, struct request **rqp) { struct request *rq = *rqp; - const int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq); + const int is_barrier = rq->cmd_type == REQ_TYPE_FS && + (rq->cmd_flags & REQ_HARDBARRIER); if (!q->ordseq) { if (!is_barrier) @@ -261,7 +262,7 @@ bool blk_do_ordered(struct request_queue *q, struct request **rqp) */ /* Special requests are not subject to ordering rules. */ - if (!blk_fs_request(rq) && + if (rq->cmd_type != REQ_TYPE_FS && rq != &q->pre_flush_rq && rq != &q->post_flush_rq) return true; diff --git a/block/blk-core.c b/block/blk-core.c index b4131d29148..dca43a31e72 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -184,7 +184,7 @@ void blk_dump_rq_flags(struct request *rq, char *msg) printk(KERN_INFO " bio %p, biotail %p, buffer %p, len %u\n", rq->bio, rq->biotail, rq->buffer, blk_rq_bytes(rq)); - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { printk(KERN_INFO " cdb: "); for (bit = 0; bit < BLK_MAX_CDB; bit++) printk("%02x ", rq->cmd[bit]); @@ -1796,7 +1796,7 @@ struct request *blk_peek_request(struct request_queue *q) * sees this request (possibly after * requeueing). Notify IO scheduler. */ - if (blk_sorted_rq(rq)) + if (rq->cmd_flags & REQ_SORTED) elv_activate_rq(q, rq); /* @@ -1984,10 +1984,11 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) * TODO: tj: This is too subtle. It would be better to let * low level drivers do what they see fit. */ - if (blk_fs_request(req)) + if (req->cmd_type == REQ_TYPE_FS) req->errors = 0; - if (error && (blk_fs_request(req) && !(req->cmd_flags & REQ_QUIET))) { + if (error && req->cmd_type == REQ_TYPE_FS && + !(req->cmd_flags & REQ_QUIET)) { printk(KERN_ERR "end_request: I/O error, dev %s, sector %llu\n", req->rq_disk ? req->rq_disk->disk_name : "?", (unsigned long long)blk_rq_pos(req)); @@ -2074,7 +2075,7 @@ bool blk_update_request(struct request *req, int error, unsigned int nr_bytes) req->buffer = bio_data(req->bio); /* update sector only for requests with clear definition of sector */ - if (blk_fs_request(req) || blk_discard_rq(req)) + if (req->cmd_type == REQ_TYPE_FS || (req->cmd_flags & REQ_DISCARD)) req->__sector += total_bytes >> 9; /* mixed attributes always follow the first bio */ @@ -2127,7 +2128,7 @@ static void blk_finish_request(struct request *req, int error) BUG_ON(blk_queued_rq(req)); - if (unlikely(laptop_mode) && blk_fs_request(req)) + if (unlikely(laptop_mode) && req->cmd_type == REQ_TYPE_FS) laptop_io_completion(&req->q->backing_dev_info); blk_delete_timer(req); diff --git a/block/blk-exec.c b/block/blk-exec.c index 49557e91f0d..e1672f14840 100644 --- a/block/blk-exec.c +++ b/block/blk-exec.c @@ -57,7 +57,7 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk, __elv_add_request(q, rq, where, 1); __generic_unplug_device(q); /* the queue is stopped so it won't be plugged+unplugged */ - if (blk_pm_resume_request(rq)) + if (rq->cmd_type == REQ_TYPE_PM_RESUME) q->request_fn(q); spin_unlock_irq(q->queue_lock); } diff --git a/block/blk-merge.c b/block/blk-merge.c index 5e7dc997345..87e4fb7d0e9 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c @@ -226,7 +226,7 @@ int ll_back_merge_fn(struct request_queue *q, struct request *req, { unsigned short max_sectors; - if (unlikely(blk_pc_request(req))) + if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC)) max_sectors = queue_max_hw_sectors(q); else max_sectors = queue_max_sectors(q); @@ -250,7 +250,7 @@ int ll_front_merge_fn(struct request_queue *q, struct request *req, { unsigned short max_sectors; - if (unlikely(blk_pc_request(req))) + if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC)) max_sectors = queue_max_hw_sectors(q); else max_sectors = queue_max_sectors(q); diff --git a/block/blk.h b/block/blk.h index 5ee3d7e72fe..6e7dc87141e 100644 --- a/block/blk.h +++ b/block/blk.h @@ -161,8 +161,10 @@ static inline int blk_cpu_to_group(int cpu) */ static inline int blk_do_io_stat(struct request *rq) { - return rq->rq_disk && blk_rq_io_stat(rq) && - (blk_fs_request(rq) || blk_discard_rq(rq)); + return rq->rq_disk && + (rq->cmd_flags & REQ_IO_STAT) && + (rq->cmd_type == REQ_TYPE_FS || + (rq->cmd_flags & REQ_DISCARD)); } #endif diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 7982b830db5..d4edeb8fceb 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -646,9 +646,10 @@ cfq_choose_req(struct cfq_data *cfqd, struct request *rq1, struct request *rq2, return rq1; else if (rq_is_sync(rq2) && !rq_is_sync(rq1)) return rq2; - if (rq_is_meta(rq1) && !rq_is_meta(rq2)) + if ((rq1->cmd_flags & REQ_RW_META) && !(rq2->cmd_flags & REQ_RW_META)) return rq1; - else if (rq_is_meta(rq2) && !rq_is_meta(rq1)) + else if ((rq2->cmd_flags & REQ_RW_META) && + !(rq1->cmd_flags & REQ_RW_META)) return rq2; s1 = blk_rq_pos(rq1); @@ -1484,7 +1485,7 @@ static void cfq_remove_request(struct request *rq) cfqq->cfqd->rq_queued--; cfq_blkiocg_update_io_remove_stats(&(RQ_CFQG(rq))->blkg, rq_data_dir(rq), rq_is_sync(rq)); - if (rq_is_meta(rq)) { + if (rq->cmd_flags & REQ_RW_META) { WARN_ON(!cfqq->meta_pending); cfqq->meta_pending--; } @@ -3176,7 +3177,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, * So both queues are sync. Let the new request get disk time if * it's a metadata request and the current queue is doing regular IO. */ - if (rq_is_meta(rq) && !cfqq->meta_pending) + if ((rq->cmd_flags & REQ_RW_META) && !cfqq->meta_pending) return true; /* @@ -3230,7 +3231,7 @@ cfq_rq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, struct cfq_io_context *cic = RQ_CIC(rq); cfqd->rq_queued++; - if (rq_is_meta(rq)) + if (rq->cmd_flags & REQ_RW_META) cfqq->meta_pending++; cfq_update_io_thinktime(cfqd, cic); @@ -3365,7 +3366,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) unsigned long now; now = jiffies; - cfq_log_cfqq(cfqd, cfqq, "complete rqnoidle %d", !!rq_noidle(rq)); + cfq_log_cfqq(cfqd, cfqq, "complete rqnoidle %d", + !!(rq->cmd_flags & REQ_NOIDLE)); cfq_update_hw_tag(cfqd); @@ -3419,11 +3421,12 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) cfq_slice_expired(cfqd, 1); else if (sync && cfqq_empty && !cfq_close_cooperator(cfqd, cfqq)) { - cfqd->noidle_tree_requires_idle |= !rq_noidle(rq); + cfqd->noidle_tree_requires_idle |= + !(rq->cmd_flags & REQ_NOIDLE); /* * Idling is enabled for SYNC_WORKLOAD. * SYNC_NOIDLE_WORKLOAD idles at the end of the tree - * only if we processed at least one !rq_noidle request + * only if we processed at least one !REQ_NOIDLE request */ if (cfqd->serving_type == SYNC_WORKLOAD || cfqd->noidle_tree_requires_idle diff --git a/block/elevator.c b/block/elevator.c index 923a9139106..aa99b59c03d 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -428,7 +428,8 @@ void elv_dispatch_sort(struct request_queue *q, struct request *rq) list_for_each_prev(entry, &q->queue_head) { struct request *pos = list_entry_rq(entry); - if (blk_discard_rq(rq) != blk_discard_rq(pos)) + if ((rq->cmd_flags & REQ_DISCARD) != + (pos->cmd_flags & REQ_DISCARD)) break; if (rq_data_dir(rq) != rq_data_dir(pos)) break; @@ -558,7 +559,7 @@ void elv_requeue_request(struct request_queue *q, struct request *rq) */ if (blk_account_rq(rq)) { q->in_flight[rq_is_sync(rq)]--; - if (blk_sorted_rq(rq)) + if (rq->cmd_flags & REQ_SORTED) elv_deactivate_rq(q, rq); } @@ -644,7 +645,8 @@ void elv_insert(struct request_queue *q, struct request *rq, int where) break; case ELEVATOR_INSERT_SORT: - BUG_ON(!blk_fs_request(rq) && !blk_discard_rq(rq)); + BUG_ON(rq->cmd_type != REQ_TYPE_FS && + !(rq->cmd_flags & REQ_DISCARD)); rq->cmd_flags |= REQ_SORTED; q->nr_sorted++; if (rq_mergeable(rq)) { @@ -716,7 +718,7 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where, /* * toggle ordered color */ - if (blk_barrier_rq(rq)) + if (rq->cmd_flags & REQ_HARDBARRIER) q->ordcolor ^= 1; /* @@ -729,7 +731,8 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where, * this request is scheduling boundary, update * end_sector */ - if (blk_fs_request(rq) || blk_discard_rq(rq)) { + if (rq->cmd_type == REQ_TYPE_FS || + (rq->cmd_flags & REQ_DISCARD)) { q->end_sector = rq_end_sector(rq); q->boundary_rq = rq; } @@ -843,7 +846,8 @@ void elv_completed_request(struct request_queue *q, struct request *rq) */ if (blk_account_rq(rq)) { q->in_flight[rq_is_sync(rq)]--; - if (blk_sorted_rq(rq) && e->ops->elevator_completed_req_fn) + if ((rq->cmd_flags & REQ_SORTED) && + e->ops->elevator_completed_req_fn) e->ops->elevator_completed_req_fn(q, rq); } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index a54273d2c3c..a5c08b082ed 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1111,7 +1111,7 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev) */ static int atapi_drain_needed(struct request *rq) { - if (likely(!blk_pc_request(rq))) + if (likely(rq->cmd_type != REQ_TYPE_BLOCK_PC)) return 0; if (!blk_rq_bytes(rq) || (rq->cmd_flags & REQ_RW)) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 10a0268a1f9..11b377762b8 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1783,7 +1783,7 @@ static void cciss_softirq_done(struct request *rq) #endif /* CCISS_DEBUG */ /* set the residual count for pc requests */ - if (blk_pc_request(rq)) + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) rq->resid_len = cmd->err_info->ResidualCnt; blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); @@ -2983,7 +2983,7 @@ static inline int evaluate_target_status(ctlr_info_t *h, driver_byte = DRIVER_OK; msg_byte = cmd->err_info->CommandStatus; /* correct? seems too device specific */ - if (blk_pc_request(cmd->rq)) + if (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) host_byte = DID_PASSTHROUGH; else host_byte = DID_OK; @@ -2992,7 +2992,7 @@ static inline int evaluate_target_status(ctlr_info_t *h, host_byte, driver_byte); if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) { - if (!blk_pc_request(cmd->rq)) + if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) printk(KERN_WARNING "cciss: cmd %p " "has SCSI Status 0x%x\n", cmd, cmd->err_info->ScsiStatus); @@ -3002,15 +3002,17 @@ static inline int evaluate_target_status(ctlr_info_t *h, /* check the sense key */ sense_key = 0xf & cmd->err_info->SenseInfo[2]; /* no status or recovered error */ - if (((sense_key == 0x0) || (sense_key == 0x1)) && !blk_pc_request(cmd->rq)) + if (((sense_key == 0x0) || (sense_key == 0x1)) && + (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC)) error_value = 0; if (check_for_unit_attention(h, cmd)) { - *retry_cmd = !blk_pc_request(cmd->rq); + *retry_cmd = !(cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC); return 0; } - if (!blk_pc_request(cmd->rq)) { /* Not SG_IO or similar? */ + /* Not SG_IO or similar? */ + if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) { if (error_value != 0) printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" " sense key = 0x%x\n", cmd, sense_key); @@ -3052,7 +3054,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, rq->errors = evaluate_target_status(h, cmd, &retry_cmd); break; case CMD_DATA_UNDERRUN: - if (blk_fs_request(cmd->rq)) { + if (cmd->rq->cmd_type == REQ_TYPE_FS) { printk(KERN_WARNING "cciss: cmd %p has" " completed with data underrun " "reported\n", cmd); @@ -3060,7 +3062,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, } break; case CMD_DATA_OVERRUN: - if (blk_fs_request(cmd->rq)) + if (cmd->rq->cmd_type == REQ_TYPE_FS) printk(KERN_WARNING "cciss: cmd %p has" " completed with data overrun " "reported\n", cmd); @@ -3070,42 +3072,48 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, "reported invalid\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; case CMD_PROTOCOL_ERR: printk(KERN_WARNING "cciss: cmd %p has " "protocol error \n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; case CMD_HARDWARE_ERR: printk(KERN_WARNING "cciss: cmd %p had " " hardware error\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; case CMD_CONNECTION_LOST: printk(KERN_WARNING "cciss: cmd %p had " "connection lost\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; case CMD_ABORTED: printk(KERN_WARNING "cciss: cmd %p was " "aborted\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ABORT); break; case CMD_ABORT_FAILED: printk(KERN_WARNING "cciss: cmd %p reports " "abort failed\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; case CMD_UNSOLICITED_ABORT: printk(KERN_WARNING "cciss%d: unsolicited " @@ -3121,13 +3129,15 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, "many times\n", h->ctlr, cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ABORT); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ABORT); break; case CMD_TIMEOUT: printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); break; default: printk(KERN_WARNING "cciss: cmd %p returned " @@ -3135,7 +3145,8 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, cmd->err_info->CommandStatus); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, - blk_pc_request(cmd->rq) ? DID_PASSTHROUGH : DID_ERROR); + (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + DID_PASSTHROUGH : DID_ERROR); } after_error_processing: @@ -3294,7 +3305,7 @@ static void do_cciss_request(struct request_queue *q) c->Header.SGList = h->max_cmd_sgentries; set_performant_mode(h, c); - if (likely(blk_fs_request(creq))) { + if (likely(creq->cmd_type == REQ_TYPE_FS)) { if(h->cciss_read == CCISS_READ_10) { c->Request.CDB[1] = 0; c->Request.CDB[2] = (start_blk >> 24) & 0xff; /* MSB */ @@ -3324,7 +3335,7 @@ static void do_cciss_request(struct request_queue *q) c->Request.CDB[13]= blk_rq_sectors(creq) & 0xff; c->Request.CDB[14] = c->Request.CDB[15] = 0; } - } else if (blk_pc_request(creq)) { + } else if (creq->cmd_type == REQ_TYPE_BLOCK_PC) { c->Request.CDBLen = creq->cmd_len; memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); } else { diff --git a/drivers/block/hd.c b/drivers/block/hd.c index 81c78b3ce2d..30ec6b37424 100644 --- a/drivers/block/hd.c +++ b/drivers/block/hd.c @@ -627,7 +627,7 @@ repeat: req_data_dir(req) == READ ? "read" : "writ", cyl, head, sec, nsect, req->buffer); #endif - if (blk_fs_request(req)) { + if (req->cmd_type == REQ_TYPE_FS) { switch (rq_data_dir(req)) { case READ: hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ, diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c index 28db925dbda..b82c5ce5e9d 100644 --- a/drivers/block/mg_disk.c +++ b/drivers/block/mg_disk.c @@ -670,7 +670,7 @@ static void mg_request_poll(struct request_queue *q) break; } - if (unlikely(!blk_fs_request(host->req))) { + if (unlikely(host->req->cmd_type != REQ_TYPE_FS)) { mg_end_request_cur(host, -EIO); continue; } @@ -756,7 +756,7 @@ static void mg_request(struct request_queue *q) continue; } - if (unlikely(!blk_fs_request(req))) { + if (unlikely(req->cmd_type != REQ_TYPE_FS)) { mg_end_request_cur(host, -EIO); continue; } diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 218d091f3c5..2e74e7d475c 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -448,7 +448,7 @@ static void nbd_clear_que(struct nbd_device *lo) static void nbd_handle_req(struct nbd_device *lo, struct request *req) { - if (!blk_fs_request(req)) + if (req->cmd_type != REQ_TYPE_FS) goto error_out; nbd_cmd(req) = NBD_CMD_READ; diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c index 6cd8b705b11..819002ba343 100644 --- a/drivers/block/osdblk.c +++ b/drivers/block/osdblk.c @@ -310,7 +310,8 @@ static void osdblk_rq_fn(struct request_queue *q) break; /* filter out block requests we don't understand */ - if (!blk_fs_request(rq) && !blk_barrier_rq(rq)) { + if (rq->cmd_type != REQ_TYPE_FS && + !(rq->cmd_flags & REQ_HARDBARRIER)) { blk_end_request_all(rq, 0); continue; } diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index c1e5cd029b2..4e8b9bff3ab 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -439,7 +439,7 @@ static char *pd_buf; /* buffer for request in progress */ static enum action do_pd_io_start(void) { - if (blk_special_request(pd_req)) { + if (pd_req->cmd_type == REQ_TYPE_SPECIAL) { phase = pd_special; return pd_special(); } diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 3b419e3fffa..5f208c0bf15 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -196,7 +196,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); while ((req = blk_fetch_request(q))) { - if (blk_fs_request(req)) { + if (req->cmd_type == REQ_TYPE_FS) { if (ps3disk_submit_request_sg(dev, req)) break; } else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 0536b5b29ad..034b34440ff 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -648,7 +648,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) return 0; } - if (lun->changed && !blk_pc_request(rq)) { + if (lun->changed && rq->cmd_type != REQ_TYPE_BLOCK_PC) blk_start_request(rq); ub_end_rq(rq, SAM_STAT_CHECK_CONDITION); return 0; @@ -684,7 +684,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq) } urq->nsg = n_elem; - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { ub_cmd_build_packet(sc, lun, cmd, urq); } else { ub_cmd_build_block(sc, lun, cmd, urq); @@ -781,7 +781,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rq = urq->rq; if (cmd->error == 0) { - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { if (cmd->act_len >= rq->resid_len) rq->resid_len = 0; else @@ -795,7 +795,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) } } } else { - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */ memcpy(rq->sense, sc->top_sense, UB_SENSE_SIZE); rq->sense_len = UB_SENSE_SIZE; diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 788d93882ab..5663d3c284c 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -361,7 +361,7 @@ static void do_viodasd_request(struct request_queue *q) if (req == NULL) return; /* check that request contains a valid command */ - if (!blk_fs_request(req)) { + if (req->cmd_type != REQ_TYPE_FS) { viodasd_end_request(req, -EIO, blk_rq_sectors(req)); continue; } diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 258bc2ae288..774144334ec 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -65,13 +65,16 @@ static void blk_done(struct virtqueue *vq) break; } - if (blk_pc_request(vbr->req)) { + switch (vbr->req->cmd_type) { + case REQ_TYPE_BLOCK_PC: vbr->req->resid_len = vbr->in_hdr.residual; vbr->req->sense_len = vbr->in_hdr.sense_len; vbr->req->errors = vbr->in_hdr.errors; - } - if (blk_special_request(vbr->req)) + break; + case REQ_TYPE_SPECIAL: vbr->req->errors = (error != 0); + break; + } __blk_end_request_all(vbr->req, error); list_del(&vbr->list); @@ -123,7 +126,7 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, BUG(); } - if (blk_barrier_rq(vbr->req)) + if (vbr->req->cmd_flags & REQ_HARDBARRIER) vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER; sg_set_buf(&vblk->sg[out++], &vbr->out_hdr, sizeof(vbr->out_hdr)); @@ -134,12 +137,12 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, * block, and before the normal inhdr we put the sense data and the * inhdr with additional status information before the normal inhdr. */ - if (blk_pc_request(vbr->req)) + if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) sg_set_buf(&vblk->sg[out++], vbr->req->cmd, vbr->req->cmd_len); num = blk_rq_map_sg(q, vbr->req, vblk->sg + out); - if (blk_pc_request(vbr->req)) { + if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) { sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96); sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr, sizeof(vbr->in_hdr)); diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 18a80ff57ce..4dc29837609 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -322,7 +322,7 @@ static void do_xd_request (struct request_queue * q) int res = -EIO; int retry; - if (!blk_fs_request(req)) + if (req->cmd_type != REQ_TYPE_FS) { goto done; if (block + count > get_capacity(req->rq_disk)) goto done; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 82ed403147c..495533e6654 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -238,7 +238,7 @@ static int blkif_queue_request(struct request *req) ring_req->operation = rq_data_dir(req) ? BLKIF_OP_WRITE : BLKIF_OP_READ; - if (blk_barrier_rq(req)) + if (req->cmd_flags & REQ_HARDBARRIER) ring_req->operation = BLKIF_OP_WRITE_BARRIER; ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg); @@ -309,7 +309,7 @@ static void do_blkif_request(struct request_queue *rq) blk_start_request(req); - if (!blk_fs_request(req)) { + if (req->cmd_type != REQ_TYPE_FS) { __blk_end_request_all(req, -EIO); continue; } diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index a7b83c0a7eb..ac278ac908d 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -465,7 +465,7 @@ struct request *ace_get_next_request(struct request_queue * q) struct request *req; while ((req = blk_peek_request(q)) != NULL) { - if (blk_fs_request(req)) + if (req->cmd_type == REQ_TYPE_FS) break; blk_start_request(req); __blk_end_request_all(req, -EIO); diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 03c71f7698c..7c05ddc63ae 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -643,7 +643,7 @@ static void gdrom_request(struct request_queue *rq) struct request *req; while ((req = blk_fetch_request(rq)) != NULL) { - if (!blk_fs_request(req)) { + if (req->cmd_type != REQ_TYPE_FS) { printk(KERN_DEBUG "GDROM: Non-fs request ignored\n"); __blk_end_request_all(req, -EIO); continue; diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 451cd7071b1..14e42016876 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -298,7 +298,7 @@ static void do_viocd_request(struct request_queue *q) struct request *req; while ((rwreq == 0) && ((req = blk_fetch_request(q)) != NULL)) { - if (!blk_fs_request(req)) + if (req->cmd_type != REQ_TYPE_FS) __blk_end_request_all(req, -EIO); else if (send_request(req) < 0) { printk(VIOCD_KERN_WARNING diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index f9daffd7d0e..3117a894d20 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c @@ -190,7 +190,7 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) BUG_ON(sense_len > sizeof(*sense)); - if (blk_sense_request(rq) || drive->sense_rq_armed) + if (rq->cmd_type == REQ_TYPE_SENSE || drive->sense_rq_armed) return; memset(sense, 0, sizeof(*sense)); @@ -307,13 +307,16 @@ EXPORT_SYMBOL_GPL(ide_cd_expiry); int ide_cd_get_xferlen(struct request *rq) { - if (blk_fs_request(rq)) + switch (rq->cmd_type) + case REQ_TYPE_FS: return 32768; - else if (blk_sense_request(rq) || blk_pc_request(rq) || - rq->cmd_type == REQ_TYPE_ATA_PC) + case REQ_TYPE_SENSE: + case REQ_TYPE_BLOCK_PC: + case REQ_TYPE_ATA_PC: return blk_rq_bytes(rq); - else + default: return 0; + } } EXPORT_SYMBOL_GPL(ide_cd_get_xferlen); @@ -474,12 +477,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) if (uptodate == 0) drive->failed_pc = NULL; - if (blk_special_request(rq)) { + if (rq->cmd_type == REQ_TYPE_SPECIAL) rq->errors = 0; error = 0; } else { - if (blk_fs_request(rq) == 0 && uptodate <= 0) { + if (req->cmd_type != REQ_TYPE_FS && uptodate <= 0) { if (rq->errors == 0) rq->errors = -EIO; } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 64207df8da8..26a3688de46 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -176,7 +176,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, if (!sense->valid) break; if (failed_command == NULL || - !blk_fs_request(failed_command)) + failed_command->cmd_type != REQ_TYPE_FS) break; sector = (sense->information[0] << 24) | (sense->information[1] << 16) | @@ -292,7 +292,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) "stat 0x%x", rq->cmd[0], rq->cmd_type, err, stat); - if (blk_sense_request(rq)) { + if (rq->cmd_type == REQ_TYPE_SENSE) { /* * We got an error trying to get sense info from the drive * (probably while trying to recover from a former error). @@ -303,7 +303,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) } /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ - if (blk_pc_request(rq) && !rq->errors) + if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !rq->errors) rq->errors = SAM_STAT_CHECK_CONDITION; if (blk_noretry_request(rq)) @@ -311,13 +311,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) switch (sense_key) { case NOT_READY: - if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { + if (rq->cmd_type == REQ_TYPE_FS && rq_data_dir(rq) == WRITE) { if (ide_cd_breathe(drive, rq)) return 1; } else { cdrom_saw_media_change(drive); - if (blk_fs_request(rq) && !blk_rq_quiet(rq)) + if (rq->cmd_type == REQ_TYPE_FS && + !(rq->cmd_flags & REQ_QUIET)) { printk(KERN_ERR PFX "%s: tray open\n", drive->name); } @@ -326,7 +327,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) case UNIT_ATTENTION: cdrom_saw_media_change(drive); - if (blk_fs_request(rq) == 0) + if (rq->cmd_type != REQ_TYPE_FS) return 0; /* @@ -352,7 +353,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * No point in retrying after an illegal request or data * protect error. */ - if (!blk_rq_quiet(rq)) + if (!(rq->cmd_flags & REQ_QUIET)) ide_dump_status(drive, "command error", stat); do_end_request = 1; break; @@ -361,20 +362,20 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) * No point in re-trying a zillion times on a bad sector. * If we got here the error is not correctable. */ - if (!blk_rq_quiet(rq)) + if (!(rq->cmd_flags & REQ_QUIET)) ide_dump_status(drive, "media error " "(bad sector)", stat); do_end_request = 1; break; case BLANK_CHECK: /* disk appears blank? */ - if (!blk_rq_quiet(rq)) + if (!(rq->cmd_flags & REQ_QUIET)) ide_dump_status(drive, "media error (blank)", stat); do_end_request = 1; break; default: - if (blk_fs_request(rq) == 0) + if (req->cmd_type != REQ_TYPE_FS) break; if (err & ~ATA_ABORTED) { /* go to the default handler for other errors */ @@ -385,7 +386,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) do_end_request = 1; } - if (blk_fs_request(rq) == 0) { + if (rq->cmd_type != REQ_TYPE_FS) { rq->cmd_flags |= REQ_FAILED; do_end_request = 1; } @@ -525,7 +526,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ide_expiry_t *expiry = NULL; int dma_error = 0, dma, thislen, uptodate = 0; int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0; - int sense = blk_sense_request(rq); + int sense = (rq->cmd_type == REQ_TYPE_SENSE); unsigned int timeout; u16 len; u8 ireason, stat; @@ -568,7 +569,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) ide_read_bcount_and_ireason(drive, &len, &ireason); - thislen = blk_fs_request(rq) ? len : cmd->nleft; + thislen = (rq->cmd_type == REQ_TYPE_FS) ? len : cmd->nleft; if (thislen > len) thislen = len; @@ -577,7 +578,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* If DRQ is clear, the command has completed. */ if ((stat & ATA_DRQ) == 0) { - if (blk_fs_request(rq)) { + if (rq->cmd_type == REQ_TYPE_FS) { /* * If we're not done reading/writing, complain. * Otherwise, complete the command normally. @@ -591,7 +592,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) rq->cmd_flags |= REQ_FAILED; uptodate = 0; } - } else if (!blk_pc_request(rq)) { + } else if (rq->cmd_type != REQ_TYPE_BLOCK_PC) { ide_cd_request_sense_fixup(drive, cmd); uptodate = cmd->nleft ? 0 : 1; @@ -640,7 +641,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) /* pad, if necessary */ if (len > 0) { - if (blk_fs_request(rq) == 0 || write == 0) + if (rq->cmd_type != REQ_TYPE_FS || write == 0) ide_pad_transfer(drive, write, len); else { printk(KERN_ERR PFX "%s: confused, missing data\n", @@ -649,11 +650,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) } } - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { timeout = rq->timeout; } else { timeout = ATAPI_WAIT_PC; - if (!blk_fs_request(rq)) + if (rq->cmd_type != REQ_TYPE_FS) expiry = ide_cd_expiry; } @@ -662,7 +663,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) return ide_started; out_end: - if (blk_pc_request(rq) && rc == 0) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) { rq->resid_len = 0; blk_end_request_all(rq, 0); hwif->rq = NULL; @@ -670,7 +671,7 @@ out_end: if (sense && uptodate) ide_cd_complete_failed_rq(drive, rq); - if (blk_fs_request(rq)) { + if (rq->cmd_type == REQ_TYPE_FS) { if (cmd->nleft == 0) uptodate = 1; } else { @@ -682,7 +683,7 @@ out_end: ide_cd_error_cmd(drive, cmd); /* make sure it's fully ended */ - if (blk_fs_request(rq) == 0) { + if (rq->cmd_type != REQ_TYPE_FS) { rq->resid_len -= cmd->nbytes - cmd->nleft; if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) rq->resid_len += cmd->last_xfer_len; @@ -742,7 +743,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", rq->cmd[0], rq->cmd_type); - if (blk_pc_request(rq)) + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) rq->cmd_flags |= REQ_QUIET; else rq->cmd_flags &= ~REQ_FAILED; @@ -783,21 +784,26 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, if (drive->debug_mask & IDE_DBG_RQ) blk_dump_rq_flags(rq, "ide_cd_do_request"); - if (blk_fs_request(rq)) { + switch (rq->cmd_type) { + case REQ_TYPE_FS: if (cdrom_start_rw(drive, rq) == ide_stopped) goto out_end; - } else if (blk_sense_request(rq) || blk_pc_request(rq) || - rq->cmd_type == REQ_TYPE_ATA_PC) { + break; + case REQ_TYPE_SENSE: + case REQ_TYPE_BLOCK_PC: + case REQ_TYPE_ATA_PC: if (!rq->timeout) rq->timeout = ATAPI_WAIT_PC; cdrom_do_block_pc(drive, rq); - } else if (blk_special_request(rq)) { + break; + case REQ_TYPE_SPECIAL: /* right now this can only be a reset... */ uptodate = 1; goto out_end; - } else + default: BUG(); + } /* prepare sense request for this command */ ide_prep_sense(drive, rq); @@ -809,7 +815,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, cmd.rq = rq; - if (blk_fs_request(rq) || blk_rq_bytes(rq)) { + if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) { ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); ide_map_sg(drive, &cmd); } @@ -1365,9 +1371,9 @@ static int ide_cdrom_prep_pc(struct request *rq) static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) { - if (blk_fs_request(rq)) + if (rq->cmd_type == REQ_TYPE_FS) return ide_cdrom_prep_fs(q, rq); - else if (blk_pc_request(rq)) + else if (rq->cmd_type == REQ_TYPE_BLOCK_PC) return ide_cdrom_prep_pc(rq); return 0; diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 33d65039cce..df3d91ba1c9 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -184,7 +184,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, ide_hwif_t *hwif = drive->hwif; BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); - BUG_ON(!blk_fs_request(rq)); + BUG_ON(rq->cmd_type != REQ_TYPE_FS); ledtrig_ide_activity(); diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c index e9abf2c3c33..c0aa93fb7a6 100644 --- a/drivers/ide/ide-eh.c +++ b/drivers/ide/ide-eh.c @@ -122,7 +122,7 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat) return ide_stopped; /* retry only "normal" I/O: */ - if (!blk_fs_request(rq)) { + if (rq->cmd_type != REQ_TYPE_FS) { if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { struct ide_cmd *cmd = rq->special; @@ -146,7 +146,8 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err) { struct request *rq = drive->hwif->rq; - if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) { + if (rq && rq->cmd_type == REQ_TYPE_SPECIAL && + rq->cmd[0] == REQ_DRIVE_RESET) { if (err <= 0 && rq->errors == 0) rq->errors = -EIO; ide_complete_rq(drive, err ? err : 0, blk_rq_bytes(rq)); diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 4713bdca20b..c7d0737bb18 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c @@ -73,7 +73,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) drive->failed_pc = NULL; if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 || - (rq && blk_pc_request(rq))) + (rq && rq->cmd_type == REQ_TYPE_BLOCK_PC)) uptodate = 1; /* FIXME */ else if (pc->c[0] == GPCMD_REQUEST_SENSE) { @@ -98,7 +98,7 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) "Aborting request!\n"); } - if (blk_special_request(rq)) + if (rq->cmd_type == REQ_TYPE_SPECIAL) rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL; return uptodate; @@ -247,14 +247,16 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, } else printk(KERN_ERR PFX "%s: I/O error\n", drive->name); - if (blk_special_request(rq)) { + if (rq->cmd_type == REQ_TYPE_SPECIAL) { rq->errors = 0; ide_complete_rq(drive, 0, blk_rq_bytes(rq)); return ide_stopped; } else goto out_end; } - if (blk_fs_request(rq)) { + + switch (rq->cmd_type) { + case REQ_TYPE_FS: if (((long)blk_rq_pos(rq) % floppy->bs_factor) || (blk_rq_sectors(rq) % floppy->bs_factor)) { printk(KERN_ERR PFX "%s: unsupported r/w rq size\n", @@ -263,13 +265,18 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, } pc = &floppy->queued_pc; idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block); - } else if (blk_special_request(rq) || blk_sense_request(rq)) { + break; + case REQ_TYPE_SPECIAL: + case REQ_TYPE_SENSE: pc = (struct ide_atapi_pc *)rq->special; - } else if (blk_pc_request(rq)) { + break; + case REQ_TYPE_BLOCK_PC: pc = &floppy->queued_pc; idefloppy_blockpc_cmd(floppy, pc, rq); - } else + break; + default: BUG(); + } ide_prep_sense(drive, rq); @@ -280,7 +287,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, cmd.rq = rq; - if (blk_fs_request(rq) || blk_rq_bytes(rq)) { + if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) { ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); ide_map_sg(drive, &cmd); } @@ -290,7 +297,7 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, return ide_floppy_issue_pc(drive, &cmd, pc); out_end: drive->failed_pc = NULL; - if (blk_fs_request(rq) == 0 && rq->errors == 0) + if (rq->cmd_type != REQ_TYPE_FS && rq->errors == 0) rq->errors = -EIO; ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); return ide_stopped; diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 172ac921815..9304a7e54d9 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -135,7 +135,7 @@ EXPORT_SYMBOL(ide_complete_rq); void ide_kill_rq(ide_drive_t *drive, struct request *rq) { - u8 drv_req = blk_special_request(rq) && rq->rq_disk; + u8 drv_req = (rq->cmd_type == REQ_TYPE_SPECIAL) && rq->rq_disk; u8 media = drive->media; drive->failed_pc = NULL; @@ -145,7 +145,7 @@ void ide_kill_rq(ide_drive_t *drive, struct request *rq) } else { if (media == ide_tape) rq->errors = IDE_DRV_ERROR_GENERAL; - else if (blk_fs_request(rq) == 0 && rq->errors == 0) + else if (rq->cmd_type != REQ_TYPE_FS && rq->errors == 0) rq->errors = -EIO; } @@ -307,7 +307,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) { ide_startstop_t startstop; - BUG_ON(!blk_rq_started(rq)); + BUG_ON(!(rq->cmd_flags & REQ_STARTED)); #ifdef DEBUG printk("%s: start_request: current=0x%08lx\n", @@ -353,7 +353,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq) pm->pm_step == IDE_PM_COMPLETED) ide_complete_pm_rq(drive, rq); return startstop; - } else if (!rq->rq_disk && blk_special_request(rq)) + } else if (!rq->rq_disk && rq->cmd_type == REQ_TYPE_SPECIAL) { /* * TODO: Once all ULDs have been modified to * check for specific op codes rather than diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c index 1c08311b0a0..92406097efe 100644 --- a/drivers/ide/ide-pm.c +++ b/drivers/ide/ide-pm.c @@ -191,10 +191,10 @@ void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq) #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, - blk_pm_suspend_request(rq) ? "suspend" : "resume"); + (rq->cmd_type == REQ_TYPE_PM_SUSPEND) ? "suspend" : "resume"); #endif spin_lock_irqsave(q->queue_lock, flags); - if (blk_pm_suspend_request(rq)) + if (rq->cmd_type == REQ_TYPE_PM_SUSPEND) blk_stop_queue(q); else drive->dev_flags &= ~IDE_DFLAG_BLOCKED; @@ -210,11 +210,11 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq) { struct request_pm_state *pm = rq->special; - if (blk_pm_suspend_request(rq) && + if (rq->cmd_type == REQ_TYPE_PM_SUSPEND && pm->pm_step == IDE_PM_START_SUSPEND) /* Mark drive blocked when starting the suspend sequence. */ drive->dev_flags |= IDE_DFLAG_BLOCKED; - else if (blk_pm_resume_request(rq) && + else if (rq->cmd_type == REQ_TYPE_PM_RESUME && pm->pm_step == IDE_PM_START_RESUME) { /* * The first thing we do on wakeup is to wait for BSY bit to diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index b07232880ec..635fd72d472 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -577,7 +577,8 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, rq->cmd[0], (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); - BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq))); + BUG_ON(!(rq->cmd_type == REQ_TYPE_SPECIAL || + rq->cmd_type == REQ_TYPE_SENSE)); /* Retry a failed packet command */ if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d21e1284604..1e0e6dd5150 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -792,12 +792,12 @@ static void dm_end_request(struct request *clone, int error) { int rw = rq_data_dir(clone); int run_queue = 1; - bool is_barrier = blk_barrier_rq(clone); + bool is_barrier = clone->cmd_flags & REQ_HARDBARRIER; struct dm_rq_target_io *tio = clone->end_io_data; struct mapped_device *md = tio->md; struct request *rq = tio->orig; - if (blk_pc_request(rq) && !is_barrier) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !is_barrier) { rq->errors = clone->errors; rq->resid_len = clone->resid_len; @@ -844,7 +844,7 @@ void dm_requeue_unmapped_request(struct request *clone) struct request_queue *q = rq->q; unsigned long flags; - if (unlikely(blk_barrier_rq(clone))) { + if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) { /* * Barrier clones share an original request. * Leave it to dm_end_request(), which handles this special @@ -943,7 +943,7 @@ static void dm_complete_request(struct request *clone, int error) struct dm_rq_target_io *tio = clone->end_io_data; struct request *rq = tio->orig; - if (unlikely(blk_barrier_rq(clone))) { + if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) { /* * Barrier clones share an original request. So can't use * softirq_done with the original. @@ -972,7 +972,7 @@ void dm_kill_unmapped_request(struct request *clone, int error) struct dm_rq_target_io *tio = clone->end_io_data; struct request *rq = tio->orig; - if (unlikely(blk_barrier_rq(clone))) { + if (unlikely(clone->cmd_flags & REQ_HARDBARRIER)) { /* * Barrier clones share an original request. * Leave it to dm_end_request(), which handles this special diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 8327e248520..56645408d22 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -805,7 +805,8 @@ static void mspro_block_start(struct memstick_dev *card) static int mspro_block_prepare_req(struct request_queue *q, struct request *req) { - if (!blk_fs_request(req) && !blk_pc_request(req)) { + if (req->cmd_type != REQ_TYPE_FS && + req->cmd_type != REQ_TYPE_BLOCK_PC) { blk_dump_rq_flags(req, "MSPro unsupported request"); return BLKPREP_KILL; } diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index fc593fbab69..108f0c2b2bf 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -883,7 +883,7 @@ static void i2o_block_request_fn(struct request_queue *q) if (!req) break; - if (blk_fs_request(req)) { + if (req->cmd_type == REQ_TYPE_FS) { struct i2o_block_delayed_request *dreq; struct i2o_block_request *ireq = req->special; unsigned int queue_depth; diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index d6ded247d94..ec92bcbdedd 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c @@ -32,7 +32,7 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) /* * We only like normal block requests. */ - if (!blk_fs_request(req)) { + if (req->cmd_type != REQ_TYPE_FS) { blk_dump_rq_flags(req, "MMC bad request"); return BLKPREP_KILL; } diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 03e19c1965c..475af42745c 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -73,14 +73,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, buf = req->buffer; - if (!blk_fs_request(req)) + if (req->cmd_type != REQ_TYPE_FS) return -EIO; if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(req->rq_disk)) return -EIO; - if (blk_discard_rq(req)) + if (req->cmd_flags & REQ_DISCARD) return tr->discard(dev, block, nsect); switch(rq_data_dir(req)) { diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index a5d630f5f51..1b88af89d0c 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -307,7 +307,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) return FAILED; - if (blk_barrier_rq(scmd->request)) + if (scmd->request->cmd_flags & REQ_HARDBARRIER) /* * barrier requests should always retry on UA * otherwise block will get a spurious error @@ -1318,16 +1318,16 @@ int scsi_noretry_cmd(struct scsi_cmnd *scmd) case DID_OK: break; case DID_BUS_BUSY: - return blk_failfast_transport(scmd->request); + return (scmd->request->cmd_flags & REQ_FAILFAST_TRANSPORT); case DID_PARITY: - return blk_failfast_dev(scmd->request); + return (scmd->request->cmd_flags & REQ_FAILFAST_DEV); case DID_ERROR: if (msg_byte(scmd->result) == COMMAND_COMPLETE && status_byte(scmd->result) == RESERVATION_CONFLICT) return 0; /* fall through */ case DID_SOFT_ERROR: - return blk_failfast_driver(scmd->request); + return (scmd->request->cmd_flags & REQ_FAILFAST_DRIVER); } switch (status_byte(scmd->result)) { @@ -1336,7 +1336,7 @@ int scsi_noretry_cmd(struct scsi_cmnd *scmd) * assume caller has checked sense and determinted * the check condition was retryable. */ - return blk_failfast_dev(scmd->request); + return (scmd->request->cmd_flags & REQ_FAILFAST_DEV); } return 0; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1646fe7cbd4..5f1160841b0 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -722,7 +722,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) sense_deferred = scsi_sense_is_deferred(&sshdr); } - if (blk_pc_request(req)) { /* SG_IO ioctl from block level */ + if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ req->errors = result; if (result) { if (sense_valid && req->sense) { @@ -757,7 +757,8 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) } } - BUG_ON(blk_bidi_rq(req)); /* bidi not support for !blk_pc_request yet */ + /* no bidi support for !REQ_TYPE_BLOCK_PC yet */ + BUG_ON(blk_bidi_rq(req)); /* * Next deal with any sectors which we were able to correctly diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8802e48bc06..a3fdf4dc59d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -485,7 +485,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) * Discard request come in as REQ_TYPE_FS but we turn them into * block PC requests to make life easier. */ - if (blk_discard_rq(rq)) + if (rq->cmd_flags & REQ_DISCARD) ret = sd_prepare_discard(rq); if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { @@ -636,7 +636,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[0] = VARIABLE_LENGTH_CMD; SCpnt->cmnd[7] = 0x18; SCpnt->cmnd[9] = (rq_data_dir(rq) == READ) ? READ_32 : WRITE_32; - SCpnt->cmnd[10] = protect | (blk_fua_rq(rq) ? 0x8 : 0); + SCpnt->cmnd[10] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); /* LBA */ SCpnt->cmnd[12] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; @@ -661,7 +661,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[31] = (unsigned char) this_count & 0xff; } else if (block > 0xffffffff) { SCpnt->cmnd[0] += READ_16 - READ_6; - SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0); + SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); SCpnt->cmnd[2] = sizeof(block) > 4 ? (unsigned char) (block >> 56) & 0xff : 0; SCpnt->cmnd[3] = sizeof(block) > 4 ? (unsigned char) (block >> 48) & 0xff : 0; SCpnt->cmnd[4] = sizeof(block) > 4 ? (unsigned char) (block >> 40) & 0xff : 0; @@ -682,7 +682,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) this_count = 0xffff; SCpnt->cmnd[0] += READ_10 - READ_6; - SCpnt->cmnd[1] = protect | (blk_fua_rq(rq) ? 0x8 : 0); + SCpnt->cmnd[1] = protect | ((rq->cmd_flags & REQ_FUA) ? 0x8 : 0); SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff; SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff; SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff; @@ -691,7 +691,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff; SCpnt->cmnd[8] = (unsigned char) this_count & 0xff; } else { - if (unlikely(blk_fua_rq(rq))) { + if (unlikely(rq->cmd_flags & REQ_FUA)) { /* * This happens only if this drive failed * 10byte rw command with ILLEGAL_REQUEST @@ -1112,7 +1112,7 @@ static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd) u64 bad_lba; int info_valid; - if (!blk_fs_request(scmd->request)) + if (scmd->request->cmd_type != REQ_TYPE_FS) return 0; info_valid = scsi_get_sense_info_fld(scmd->sense_buffer, diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index b5838d547c6..713620ed70d 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c @@ -2022,7 +2022,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) if((count > SUN3_DMA_MINSIZE) && (sun3_dma_setup_done != cmd)) { - if(blk_fs_request(cmd->request)) { + if (cmd->request->cmd_type == REQ_TYPE_FS) { sun3scsi_dma_setup(d, count, rq_data_dir(cmd->request)); sun3_dma_setup_done = cmd; diff --git a/drivers/scsi/sun3_scsi.c b/drivers/scsi/sun3_scsi.c index e606cf0a2eb..613f5880d13 100644 --- a/drivers/scsi/sun3_scsi.c +++ b/drivers/scsi/sun3_scsi.c @@ -524,7 +524,7 @@ static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, struct scsi_cmnd *cmd, int write_flag) { - if(blk_fs_request(cmd->request)) + if (cmd->request->cmd_type == REQ_TYPE_FS) return wanted; else return 0; diff --git a/drivers/scsi/sun3_scsi_vme.c b/drivers/scsi/sun3_scsi_vme.c index aaa4fd0dd1b..7c526b8e30a 100644 --- a/drivers/scsi/sun3_scsi_vme.c +++ b/drivers/scsi/sun3_scsi_vme.c @@ -458,7 +458,7 @@ static inline unsigned long sun3scsi_dma_xfer_len(unsigned long wanted, struct scsi_cmnd *cmd, int write_flag) { - if(blk_fs_request(cmd->request)) + if (cmd->request->cmd_type == REQ_TYPE_FS) return wanted; else return 0; diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 61bd0be5fb1..a9aff90e58e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -823,7 +823,8 @@ static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req) blkvsc_req->cmnd[0] = READ_16; } - blkvsc_req->cmnd[1] |= blk_fua_rq(blkvsc_req->req) ? 0x8 : 0; + blkvsc_req->cmnd[1] |= + (blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0; *(unsigned long long *)&blkvsc_req->cmnd[2] = cpu_to_be64(blkvsc_req->sector_start); @@ -839,7 +840,8 @@ static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req) blkvsc_req->cmnd[0] = READ_10; } - blkvsc_req->cmnd[1] |= blk_fua_rq(blkvsc_req->req) ? 0x8 : 0; + blkvsc_req->cmnd[1] |= + (blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0; *(unsigned int *)&blkvsc_req->cmnd[2] = cpu_to_be32(blkvsc_req->sector_start); @@ -1286,7 +1288,7 @@ static void blkvsc_request(struct request_queue *queue) DPRINT_DBG(BLKVSC_DRV, "- req %p\n", req); blkdev = req->rq_disk->private_data; - if (blkdev->shutting_down || !blk_fs_request(req) || + if (blkdev->shutting_down || req->cmd_type != REQ_TYPE_FS || blkdev->media_not_present) { __blk_end_request_cur(req, 0); continue; diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d7ae241a9e5..3ecd28ef9ba 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -604,33 +604,20 @@ enum { test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) #define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags) -#define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) -#define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) -#define blk_special_request(rq) ((rq)->cmd_type == REQ_TYPE_SPECIAL) -#define blk_sense_request(rq) ((rq)->cmd_type == REQ_TYPE_SENSE) - -#define blk_failfast_dev(rq) ((rq)->cmd_flags & REQ_FAILFAST_DEV) -#define blk_failfast_transport(rq) ((rq)->cmd_flags & REQ_FAILFAST_TRANSPORT) -#define blk_failfast_driver(rq) ((rq)->cmd_flags & REQ_FAILFAST_DRIVER) -#define blk_noretry_request(rq) (blk_failfast_dev(rq) || \ - blk_failfast_transport(rq) || \ - blk_failfast_driver(rq)) -#define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) -#define blk_rq_io_stat(rq) ((rq)->cmd_flags & REQ_IO_STAT) -#define blk_rq_quiet(rq) ((rq)->cmd_flags & REQ_QUIET) - -#define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) - -#define blk_pm_suspend_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND) -#define blk_pm_resume_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_RESUME) +#define blk_noretry_request(rq) \ + ((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \ + REQ_FAILFAST_DRIVER)) + +#define blk_account_rq(rq) \ + (((rq)->cmd_flags & REQ_STARTED) && \ + ((rq)->cmd_type == REQ_TYPE_FS || \ + ((rq)->cmd_flags & REQ_DISCARD))) + #define blk_pm_request(rq) \ - (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq)) + ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND || \ + (rq)->cmd_type == REQ_TYPE_PM_RESUME) #define blk_rq_cpu_valid(rq) ((rq)->cpu != -1) -#define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED) -#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER) -#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) -#define blk_discard_rq(rq) ((rq)->cmd_flags & REQ_DISCARD) #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) /* rq->queuelist of dequeued request must be list_empty() */ #define blk_queued_rq(rq) (!list_empty(&(rq)->queuelist)) @@ -652,9 +639,6 @@ static inline bool rq_is_sync(struct request *rq) return rw_is_sync(rq->cmd_flags); } -#define rq_is_meta(rq) ((rq)->cmd_flags & REQ_RW_META) -#define rq_noidle(rq) ((rq)->cmd_flags & REQ_NOIDLE) - static inline int blk_queue_full(struct request_queue *q, int sync) { if (sync) @@ -687,7 +671,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int sync) (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER) #define rq_mergeable(rq) \ (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ - (blk_discard_rq(rq) || blk_fs_request((rq)))) + (((rq)->cmd_flags & REQ_DISCARD) || \ + (rq)->cmd_type == REQ_TYPE_FS)) /* * q->prep_rq_fn return values diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 416bf62d6d4..23faa67e802 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -224,7 +224,7 @@ static inline int blk_trace_init_sysfs(struct device *dev) static inline int blk_cmd_buf_len(struct request *rq) { - return blk_pc_request(rq) ? rq->cmd_len * 3 : 1; + return (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? rq->cmd_len * 3 : 1; } extern void blk_dump_cmd(char *buf, struct request *rq); diff --git a/include/trace/events/block.h b/include/trace/events/block.h index d870a918559..d8ce278515c 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -25,8 +25,10 @@ DECLARE_EVENT_CLASS(block_rq_with_error, TP_fast_assign( __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0; - __entry->sector = blk_pc_request(rq) ? 0 : blk_rq_pos(rq); - __entry->nr_sector = blk_pc_request(rq) ? 0 : blk_rq_sectors(rq); + __entry->sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq); + __entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq); __entry->errors = rq->errors; blk_fill_rwbs_rq(__entry->rwbs, rq); @@ -109,9 +111,12 @@ DECLARE_EVENT_CLASS(block_rq, TP_fast_assign( __entry->dev = rq->rq_disk ? disk_devt(rq->rq_disk) : 0; - __entry->sector = blk_pc_request(rq) ? 0 : blk_rq_pos(rq); - __entry->nr_sector = blk_pc_request(rq) ? 0 : blk_rq_sectors(rq); - __entry->bytes = blk_pc_request(rq) ? blk_rq_bytes(rq) : 0; + __entry->sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_pos(rq); + __entry->nr_sector = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + 0 : blk_rq_sectors(rq); + __entry->bytes = (rq->cmd_type == REQ_TYPE_BLOCK_PC) ? + blk_rq_bytes(rq) : 0; blk_fill_rwbs_rq(__entry->rwbs, rq); blk_dump_cmd(__get_str(cmd), rq); diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 638711c1750..4f149944cb8 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -661,10 +661,10 @@ static void blk_add_trace_rq(struct request_queue *q, struct request *rq, if (likely(!bt)) return; - if (blk_discard_rq(rq)) + if (rq->cmd_flags & REQ_DISCARD) rw |= (1 << BIO_RW_DISCARD); - if (blk_pc_request(rq)) { + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { what |= BLK_TC_ACT(BLK_TC_PC); __blk_add_trace(bt, 0, blk_rq_bytes(rq), rw, what, rq->errors, rq->cmd_len, rq->cmd); @@ -925,7 +925,7 @@ void blk_add_driver_data(struct request_queue *q, if (likely(!bt)) return; - if (blk_pc_request(rq)) + if (rq->cmd_type == REQ_TYPE_BLOCK_PC) __blk_add_trace(bt, 0, blk_rq_bytes(rq), 0, BLK_TA_DRV_DATA, rq->errors, len, data); else @@ -1730,7 +1730,7 @@ void blk_dump_cmd(char *buf, struct request *rq) int len = rq->cmd_len; unsigned char *cmd = rq->cmd; - if (!blk_pc_request(rq)) { + if (rq->cmd_type != REQ_TYPE_BLOCK_PC) { buf[0] = '\0'; return; } @@ -1779,7 +1779,7 @@ void blk_fill_rwbs_rq(char *rwbs, struct request *rq) int rw = rq->cmd_flags & 0x03; int bytes; - if (blk_discard_rq(rq)) + if (rq->cmd_flags & REQ_DISCARD) rw |= (1 << BIO_RW_DISCARD); bytes = blk_rq_bytes(rq); -- cgit v1.2.3-70-g09d2 From 8a6cfeb6deca3a8fefd639d898b0d163c0b5d368 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 8 Jul 2010 10:18:46 +0200 Subject: block: push down BKL into .locked_ioctl As a preparation for the removal of the big kernel lock in the block layer, this removes the BKL from the common ioctl handling code, moving it into every single driver still using it. Signed-off-by: Arnd Bergmann Acked-by: Christoph Hellwig Signed-off-by: Jens Axboe --- block/ioctl.c | 11 +---------- drivers/block/amiflop.c | 17 +++++++++++++++-- drivers/block/ataflop.c | 18 +++++++++++++++--- drivers/block/brd.c | 5 ++++- drivers/block/cciss.c | 8 +++++--- drivers/block/cpqarray.c | 18 ++++++++++++++++-- drivers/block/floppy.c | 17 +++++++++++++++-- drivers/block/nbd.c | 5 ++++- drivers/block/paride/pcd.c | 11 +++++++++-- drivers/block/paride/pd.c | 5 ++++- drivers/block/paride/pf.c | 6 +++++- drivers/block/pktcdvd.c | 13 +++++++++---- drivers/block/swim.c | 5 ++++- drivers/block/swim3.c | 17 +++++++++++++++-- drivers/block/ub.c | 10 ++++++++-- drivers/block/virtio_blk.c | 17 +++++++++++++++-- drivers/block/xd.c | 17 +++++++++++++++-- drivers/block/xen-blkfront.c | 2 +- drivers/cdrom/gdrom.c | 11 +++++++++-- drivers/cdrom/viocd.c | 11 +++++++++-- drivers/ide/ide-cd.c | 18 ++++++++++++++++-- drivers/ide/ide-disk_ioctl.c | 9 +++++++-- drivers/ide/ide-floppy_ioctl.c | 12 +++++++++--- drivers/ide/ide-gd.c | 2 +- drivers/ide/ide-tape.c | 10 ++++++++-- drivers/message/i2o/i2o_block.c | 22 +++++----------------- drivers/mtd/mtd_blkdevs.c | 5 ++++- drivers/scsi/sd.c | 17 ++++++++++++----- drivers/scsi/sr.c | 18 +++++++++++++----- include/linux/blkdev.h | 1 - 30 files changed, 253 insertions(+), 85 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/block/ioctl.c b/block/ioctl.c index e8eb679f2f9..1cfa8d449d9 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -163,18 +163,10 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct gendisk *disk = bdev->bd_disk; - int ret; if (disk->fops->ioctl) return disk->fops->ioctl(bdev, mode, cmd, arg); - if (disk->fops->locked_ioctl) { - lock_kernel(); - ret = disk->fops->locked_ioctl(bdev, mode, cmd, arg); - unlock_kernel(); - return ret; - } - return -ENOTTY; } /* @@ -185,8 +177,7 @@ int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode, EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl); /* - * always keep this in sync with compat_blkdev_ioctl() and - * compat_blkdev_locked_ioctl() + * always keep this in sync with compat_blkdev_ioctl() */ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 832798aa14f..0fa26359304 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -1423,7 +1424,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct block_device *bdev, fmode_t mode, +static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { struct amiga_floppy_struct *p = bdev->bd_disk->private_data; @@ -1500,6 +1501,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, return 0; } +static int fd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = fd_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + static void fd_probe(int dev) { unsigned long code; @@ -1638,7 +1651,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = fd_ioctl, + .ioctl = fd_ioctl, .getgeo = fd_getgeo, .media_changed = amiga_floppy_change, }; diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index e35cf59cbfd..1bb8bfcfdbd 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -359,7 +360,7 @@ static void finish_fdc( void ); static void finish_fdc_done( int dummy ); static void setup_req_params( int drive ); static void redo_fd_request( void); -static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int +static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param); static void fd_probe( int drive ); static int fd_test_drive_present( int drive ); @@ -1480,7 +1481,7 @@ void do_fd_request(struct request_queue * q) atari_enable_irq( IRQ_MFP_FDC ); } -static int fd_ioctl(struct block_device *bdev, fmode_t mode, +static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { struct gendisk *disk = bdev->bd_disk; @@ -1665,6 +1666,17 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, } } +static int fd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = fd_locked_ioctl(bdev, mode, cmd, arg); + unlock_kernel(); + + return ret; +} /* Initialize the 'unit' variable for drive 'drive' */ @@ -1855,7 +1867,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = fd_ioctl, + .ioctl = fd_ioctl, .media_changed = check_floppy_change, .revalidate_disk= floppy_revalidate, }; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 1d2c18620f9..1c7f63792ff 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include /* invalidate_bh_lrus() */ #include @@ -401,6 +402,7 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode, * ram device BLKFLSBUF has special semantics, we want to actually * release and destroy the ramdisk data. */ + lock_kernel(); mutex_lock(&bdev->bd_mutex); error = -EBUSY; if (bdev->bd_openers <= 1) { @@ -417,13 +419,14 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode, error = 0; } mutex_unlock(&bdev->bd_mutex); + unlock_kernel(); return error; } static const struct block_device_operations brd_fops = { .owner = THIS_MODULE, - .locked_ioctl = brd_ioctl, + .ioctl = brd_ioctl, #ifdef CONFIG_BLK_DEV_XIP .direct_access = brd_direct_access, #endif diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 11b377762b8..a6c0494dd05 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -179,6 +179,8 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id); static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); static int cciss_open(struct block_device *bdev, fmode_t mode); static int cciss_release(struct gendisk *disk, fmode_t mode); +static int do_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg); static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -237,7 +239,7 @@ static const struct block_device_operations cciss_fops = { .owner = THIS_MODULE, .open = cciss_open, .release = cciss_release, - .locked_ioctl = cciss_ioctl, + .ioctl = do_ioctl, .getgeo = cciss_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = cciss_compat_ioctl, @@ -1057,8 +1059,6 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) return 0; } -#ifdef CONFIG_COMPAT - static int do_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { @@ -1069,6 +1069,8 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode, return ret; } +#ifdef CONFIG_COMPAT + static int cciss_ioctl32_passthru(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg); static int cciss_ioctl32_big_passthru(struct block_device *bdev, fmode_t mode, diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index abb4ec6690f..c459aeea3c0 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -197,7 +198,7 @@ static const struct block_device_operations ida_fops = { .owner = THIS_MODULE, .open = ida_open, .release = ida_release, - .locked_ioctl = ida_ioctl, + .ioctl = ida_ioctl, .getgeo = ida_getgeo, .revalidate_disk= ida_revalidate, }; @@ -1128,7 +1129,7 @@ static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo) * ida_ioctl does some miscellaneous stuff like reporting drive geometry, * setting readahead and submitting commands from userspace to the controller. */ -static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) +static int ida_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { drv_info_t *drv = get_drv(bdev->bd_disk); ctlr_info_t *host = get_host(bdev->bd_disk); @@ -1192,6 +1193,19 @@ out_passthru: } } + +static int ida_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = ida_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + /* * ida_ctlr_ioctl is for passing commands to the controller from userspace. * The command block (io) has already been copied to kernel space for us, diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 82c30f9f81c..40419b066aa 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -178,6 +178,7 @@ static int print_unex = 1; #include #include #include +#include #include #include #include @@ -3371,7 +3372,7 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, +static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { int drive = (long)bdev->bd_disk->private_data; @@ -3547,6 +3548,18 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, return 0; } +static int fd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = fd_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + static void __init config_types(void) { bool has_drive = false; @@ -3848,7 +3861,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = fd_ioctl, + .ioctl = fd_ioctl, .getgeo = fd_getgeo, .media_changed = check_floppy_change, .revalidate_disk = floppy_revalidate, diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 2e74e7d475c..6751789fb37 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -716,9 +717,11 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n", lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg); + lock_kernel(); mutex_lock(&lo->tx_lock); error = __nbd_ioctl(bdev, lo, cmd, arg); mutex_unlock(&lo->tx_lock); + unlock_kernel(); return error; } @@ -726,7 +729,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode, static const struct block_device_operations nbd_fops = { .owner = THIS_MODULE, - .locked_ioctl = nbd_ioctl, + .ioctl = nbd_ioctl, }; /* diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index 71acf4e5335..daba7a62a66 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -138,6 +138,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; #include #include #include +#include #include static DEFINE_SPINLOCK(pcd_lock); @@ -238,7 +239,13 @@ static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct pcd_unit *cd = bdev->bd_disk->private_data; - return cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); + int ret; + + lock_kernel(); + ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); + unlock_kernel(); + + return ret; } static int pcd_block_media_changed(struct gendisk *disk) @@ -251,7 +258,7 @@ static const struct block_device_operations pcd_bdops = { .owner = THIS_MODULE, .open = pcd_block_open, .release = pcd_block_release, - .locked_ioctl = pcd_block_ioctl, + .ioctl = pcd_block_ioctl, .media_changed = pcd_block_media_changed, }; diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 4e8b9bff3ab..c4d6ed9846c 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -153,6 +153,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV}; #include #include #include +#include #include #include @@ -768,8 +769,10 @@ static int pd_ioctl(struct block_device *bdev, fmode_t mode, switch (cmd) { case CDROMEJECT: + lock_kernel(); if (disk->access == 1) pd_special_command(disk, pd_eject); + unlock_kernel(); return 0; default: return -EINVAL; @@ -812,7 +815,7 @@ static const struct block_device_operations pd_fops = { .owner = THIS_MODULE, .open = pd_open, .release = pd_release, - .locked_ioctl = pd_ioctl, + .ioctl = pd_ioctl, .getgeo = pd_getgeo, .media_changed = pd_check_media, .revalidate_disk= pd_revalidate diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index c059aab3006..38b4d566b81 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -152,6 +152,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_LUN, D_DLY}; #include #include #include +#include #include static DEFINE_SPINLOCK(pf_spin_lock); @@ -266,7 +267,7 @@ static const struct block_device_operations pf_fops = { .owner = THIS_MODULE, .open = pf_open, .release = pf_release, - .locked_ioctl = pf_ioctl, + .ioctl = pf_ioctl, .getgeo = pf_getgeo, .media_changed = pf_check_media, }; @@ -342,7 +343,10 @@ static int pf_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, u if (pf->access != 1) return -EBUSY; + lock_kernel(); pf_eject(pf); + unlock_kernel(); + return 0; } diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 9f3e4454274..40f1e31f42c 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -2762,10 +2763,12 @@ out_mem: static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct pktcdvd_device *pd = bdev->bd_disk->private_data; + int ret; VPRINTK("pkt_ioctl: cmd %x, dev %d:%d\n", cmd, MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev)); + lock_kernel(); switch (cmd) { case CDROMEJECT: /* @@ -2783,14 +2786,16 @@ static int pkt_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, case CDROM_LAST_WRITTEN: case CDROM_SEND_PACKET: case SCSI_IOCTL_SEND_COMMAND: - return __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); + ret = __blkdev_driver_ioctl(pd->bdev, mode, cmd, arg); + break; default: VPRINTK(DRIVER_NAME": Unknown ioctl for %s (%x)\n", pd->name, cmd); - return -ENOTTY; + ret = -ENOTTY; } + unlock_kernel(); - return 0; + return ret; } static int pkt_media_changed(struct gendisk *disk) @@ -2812,7 +2817,7 @@ static const struct block_device_operations pktcdvd_ops = { .owner = THIS_MODULE, .open = pkt_open, .release = pkt_close, - .locked_ioctl = pkt_ioctl, + .ioctl = pkt_ioctl, .media_changed = pkt_media_changed, }; diff --git a/drivers/block/swim.c b/drivers/block/swim.c index e463657569f..f04f74e3758 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -690,7 +691,9 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, case FDEJECT: if (fs->ref_count != 1) return -EBUSY; + lock_kernel(); err = floppy_eject(fs); + unlock_kernel(); return err; case FDGETPRM: @@ -753,7 +756,7 @@ static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, .open = floppy_open, .release = floppy_release, - .locked_ioctl = floppy_ioctl, + .ioctl = floppy_ioctl, .getgeo = floppy_getgeo, .media_changed = floppy_check_change, .revalidate_disk = floppy_revalidate, diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index ed6fb91123a..f3657b2a538 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -839,7 +840,7 @@ static int fd_eject(struct floppy_state *fs) static struct floppy_struct floppy_type = { 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL }; /* 7 1.44MB 3.5" */ -static int floppy_ioctl(struct block_device *bdev, fmode_t mode, +static int floppy_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long param) { struct floppy_state *fs = bdev->bd_disk->private_data; @@ -867,6 +868,18 @@ static int floppy_ioctl(struct block_device *bdev, fmode_t mode, return -ENOTTY; } +static int floppy_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = floppy_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + static int floppy_open(struct block_device *bdev, fmode_t mode) { struct floppy_state *fs = bdev->bd_disk->private_data; @@ -997,7 +1010,7 @@ static int floppy_revalidate(struct gendisk *disk) static const struct block_device_operations floppy_fops = { .open = floppy_open, .release = floppy_release, - .locked_ioctl = floppy_ioctl, + .ioctl = floppy_ioctl, .media_changed = floppy_check_change, .revalidate_disk= floppy_revalidate, }; diff --git a/drivers/block/ub.c b/drivers/block/ub.c index aaf27fb4efd..102ed52d0e0 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #define DRV_NAME "ub" @@ -1729,8 +1730,13 @@ static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode, { struct gendisk *disk = bdev->bd_disk; void __user *usermem = (void __user *) arg; + int ret; + + lock_kernel(); + ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); + unlock_kernel(); - return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem); + return ret; } /* @@ -1794,7 +1800,7 @@ static const struct block_device_operations ub_bd_fops = { .owner = THIS_MODULE, .open = ub_bd_open, .release = ub_bd_release, - .locked_ioctl = ub_bd_ioctl, + .ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed, .revalidate_disk = ub_bd_revalidate, }; diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 0a3222fd444..7b0f7b624ad 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -217,7 +218,7 @@ static int virtblk_get_id(struct gendisk *disk, char *id_str) return blk_execute_rq(vblk->disk->queue, vblk->disk, req, false); } -static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, +static int virtblk_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long data) { struct gendisk *disk = bdev->bd_disk; @@ -243,6 +244,18 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, (void __user *)data); } +static int virtblk_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = virtblk_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + /* We provide getgeo only to please some old bootloader/partitioning tools */ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) { @@ -269,7 +282,7 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo) } static const struct block_device_operations virtblk_fops = { - .locked_ioctl = virtblk_ioctl, + .ioctl = virtblk_ioctl, .owner = THIS_MODULE, .getgeo = virtblk_getgeo, }; diff --git a/drivers/block/xd.c b/drivers/block/xd.c index b16a3a926cf..d5a3cd75056 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +134,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo); static const struct block_device_operations xd_fops = { .owner = THIS_MODULE, - .locked_ioctl = xd_ioctl, + .ioctl = xd_ioctl, .getgeo = xd_getgeo, }; static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); @@ -347,7 +348,7 @@ static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo) } /* xd_ioctl: handle device ioctl's */ -static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) +static int xd_locked_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long arg) { switch (cmd) { case HDIO_SET_DMA: @@ -375,6 +376,18 @@ static int xd_ioctl(struct block_device *bdev, fmode_t mode, u_int cmd, u_long a } } +static int xd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long param) +{ + int ret; + + lock_kernel(); + ret = xd_locked_ioctl(bdev, mode, cmd, param); + unlock_kernel(); + + return ret; +} + /* xd_readwrite: handle a read/write request */ static int xd_readwrite (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count) { diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 76af65b654e..9119cd3d56a 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1045,7 +1045,7 @@ static const struct block_device_operations xlvbd_block_fops = .open = blkif_open, .release = blkif_release, .getgeo = blkif_getgeo, - .locked_ioctl = blkif_ioctl, + .ioctl = blkif_ioctl, }; diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 5219b57deb3..1772fd914fb 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -509,7 +510,13 @@ static int gdrom_bdops_mediachanged(struct gendisk *disk) static int gdrom_bdops_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { - return cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg); + int ret; + + lock_kernel(); + ret = cdrom_ioctl(gd.cd_info, bdev, mode, cmd, arg); + unlock_kernel(); + + return ret; } static const struct block_device_operations gdrom_bdops = { @@ -517,7 +524,7 @@ static const struct block_device_operations gdrom_bdops = { .open = gdrom_bdops_open, .release = gdrom_bdops_release, .media_changed = gdrom_bdops_mediachanged, - .locked_ioctl = gdrom_bdops_ioctl, + .ioctl = gdrom_bdops_ioctl, }; static irqreturn_t gdrom_command_interrupt(int irq, void *dev_id) diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 1fa6628d150..16dada0627e 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -167,7 +168,13 @@ static int viocd_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, unsigned long arg) { struct disk_info *di = bdev->bd_disk->private_data; - return cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg); + int ret; + + lock_kernel(); + ret = cdrom_ioctl(&di->viocd_info, bdev, mode, cmd, arg); + unlock_kernel(); + + return ret; } static int viocd_blk_media_changed(struct gendisk *disk) @@ -180,7 +187,7 @@ static const struct block_device_operations viocd_fops = { .owner = THIS_MODULE, .open = viocd_blk_open, .release = viocd_blk_release, - .locked_ioctl = viocd_blk_ioctl, + .ioctl = viocd_blk_ioctl, .media_changed = viocd_blk_media_changed, }; diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ef7e3a9bee5..bf9f61a5c2f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -1654,7 +1655,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) return 0; } -static int idecd_ioctl(struct block_device *bdev, fmode_t mode, +static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); @@ -1676,6 +1677,19 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode, return err; } +static int idecd_ioctl(struct block_device *bdev, fmode_t mode, + unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = idecd_locked_ioctl(bdev, mode, cmd, arg); + unlock_kernel(); + + return ret; +} + + static int idecd_media_changed(struct gendisk *disk) { struct cdrom_info *info = ide_drv_g(disk, cdrom_info); @@ -1696,7 +1710,7 @@ static const struct block_device_operations idecd_ops = { .owner = THIS_MODULE, .open = idecd_open, .release = idecd_release, - .locked_ioctl = idecd_ioctl, + .ioctl = idecd_ioctl, .media_changed = idecd_media_changed, .revalidate_disk = idecd_revalidate_disk }; diff --git a/drivers/ide/ide-disk_ioctl.c b/drivers/ide/ide-disk_ioctl.c index 7b783dd7c0b..ec94c66918f 100644 --- a/drivers/ide/ide-disk_ioctl.c +++ b/drivers/ide/ide-disk_ioctl.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "ide-disk.h" @@ -18,9 +19,13 @@ int ide_disk_ioctl(ide_drive_t *drive, struct block_device *bdev, fmode_t mode, { int err; + lock_kernel(); err = ide_setting_ioctl(drive, bdev, cmd, arg, ide_disk_ioctl_settings); if (err != -EOPNOTSUPP) - return err; + goto out; - return generic_ide_ioctl(drive, bdev, cmd, arg); + err = generic_ide_ioctl(drive, bdev, cmd, arg); +out: + unlock_kernel(); + return err; } diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index 9c2288234de..fd3d05ab341 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -275,12 +276,15 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, void __user *argp = (void __user *)arg; int err; - if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) - return ide_floppy_lockdoor(drive, &pc, arg, cmd); + lock_kernel(); + if (cmd == CDROMEJECT || cmd == CDROM_LOCKDOOR) { + err = ide_floppy_lockdoor(drive, &pc, arg, cmd); + goto out; + } err = ide_floppy_format_ioctl(drive, &pc, mode, cmd, argp); if (err != -ENOTTY) - return err; + goto out; /* * skip SCSI_IOCTL_SEND_COMMAND (deprecated) @@ -293,5 +297,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev, if (err == -ENOTTY) err = generic_ide_ioctl(drive, bdev, cmd, arg); +out: + unlock_kernel(); return err; } diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index c102d23d9b3..883f0c979c9 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -323,7 +323,7 @@ static const struct block_device_operations ide_gd_ops = { .owner = THIS_MODULE, .open = ide_gd_open, .release = ide_gd_release, - .locked_ioctl = ide_gd_ioctl, + .ioctl = ide_gd_ioctl, .getgeo = ide_gd_getgeo, .media_changed = ide_gd_media_changed, .unlock_native_capacity = ide_gd_unlock_native_capacity, diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 635fd72d472..39b0a5c45f0 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1927,9 +1928,14 @@ static int idetape_ioctl(struct block_device *bdev, fmode_t mode, { struct ide_tape_obj *tape = ide_drv_g(bdev->bd_disk, ide_tape_obj); ide_drive_t *drive = tape->drive; - int err = generic_ide_ioctl(drive, bdev, cmd, arg); + int err; + + lock_kernel(); + err = generic_ide_ioctl(drive, bdev, cmd, arg); if (err == -EINVAL) err = idetape_blkdev_ioctl(drive, cmd, arg); + unlock_kernel(); + return err; } @@ -1937,7 +1943,7 @@ static const struct block_device_operations idetape_block_ops = { .owner = THIS_MODULE, .open = idetape_open, .release = idetape_release, - .locked_ioctl = idetape_ioctl, + .ioctl = idetape_ioctl, }; static int ide_tape_probe(ide_drive_t *drive) diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index b8233ff863e..d1bdf8abe5d 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -53,7 +53,6 @@ #include #include #include -#include #include @@ -653,40 +652,30 @@ static int i2o_block_ioctl(struct block_device *bdev, fmode_t mode, { struct gendisk *disk = bdev->bd_disk; struct i2o_block_device *dev = disk->private_data; - int ret = -ENOTTY; /* Anyone capable of this syscall can do *real bad* things */ if (!capable(CAP_SYS_ADMIN)) return -EPERM; - lock_kernel(); switch (cmd) { case BLKI2OGRSTRAT: - ret = put_user(dev->rcache, (int __user *)arg); - break; + return put_user(dev->rcache, (int __user *)arg); case BLKI2OGWSTRAT: - ret = put_user(dev->wcache, (int __user *)arg); - break; + return put_user(dev->wcache, (int __user *)arg); case BLKI2OSRSTRAT: - ret = -EINVAL; if (arg < 0 || arg > CACHE_SMARTFETCH) - break; + return -EINVAL; dev->rcache = arg; - ret = 0; break; case BLKI2OSWSTRAT: - ret = -EINVAL; if (arg != 0 && (arg < CACHE_WRITETHROUGH || arg > CACHE_SMARTBACK)) - break; + return -EINVAL; dev->wcache = arg; - ret = 0; break; } - unlock_kernel(); - - return ret; + return -ENOTTY; }; /** @@ -942,7 +931,6 @@ static const struct block_device_operations i2o_block_fops = { .open = i2o_block_open, .release = i2o_block_release, .ioctl = i2o_block_ioctl, - .compat_ioctl = i2o_block_ioctl, .getgeo = i2o_block_getgeo, .media_changed = i2o_block_media_changed }; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 475af42745c..8c83b11a77d 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -237,6 +238,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, if (!dev) return ret; + lock_kernel(); mutex_lock(&dev->lock); if (!dev->mtd) @@ -250,6 +252,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, } unlock: mutex_unlock(&dev->lock); + unlock_kernel(); blktrans_dev_put(dev); return ret; } @@ -258,7 +261,7 @@ static const struct block_device_operations mtd_blktrans_ops = { .owner = THIS_MODULE, .open = blktrans_open, .release = blktrans_release, - .locked_ioctl = blktrans_ioctl, + .ioctl = blktrans_ioctl, .getgeo = blktrans_getgeo, }; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 1d0c4b7c3b6..633ac32b25c 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -924,6 +925,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n", disk->disk_name, cmd)); + lock_kernel(); /* * If we are in the middle of error recovery, don't let anyone * else try and use this device. Also, if error recovery fails, it @@ -933,7 +935,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, error = scsi_nonblockable_ioctl(sdp, cmd, p, (mode & FMODE_NDELAY) != 0); if (!scsi_block_when_processing_errors(sdp) || !error) - return error; + goto out; /* * Send SCSI addressing ioctls directly to mid level, send other @@ -943,13 +945,18 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode, switch (cmd) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: - return scsi_ioctl(sdp, cmd, p); + error = scsi_ioctl(sdp, cmd, p); + break; default: error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p); if (error != -ENOTTY) - return error; + break; + error = scsi_ioctl(sdp, cmd, p); + break; } - return scsi_ioctl(sdp, cmd, p); +out: + unlock_kernel(); + return error; } static void set_media_not_present(struct scsi_disk *sdkp) @@ -1123,7 +1130,7 @@ static const struct block_device_operations sd_fops = { .owner = THIS_MODULE, .open = sd_open, .release = sd_release, - .locked_ioctl = sd_ioctl, + .ioctl = sd_ioctl, .getgeo = sd_getgeo, #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 0a90abc7f14..d42fa6468f4 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -493,6 +494,8 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, void __user *argp = (void __user *)arg; int ret; + lock_kernel(); + /* * Send SCSI addressing ioctls directly to mid level, send other * ioctls to cdrom/block level. @@ -500,12 +503,13 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, switch (cmd) { case SCSI_IOCTL_GET_IDLUN: case SCSI_IOCTL_GET_BUS_NUMBER: - return scsi_ioctl(sdev, cmd, argp); + ret = scsi_ioctl(sdev, cmd, argp); + goto out; } ret = cdrom_ioctl(&cd->cdi, bdev, mode, cmd, arg); if (ret != -ENOSYS) - return ret; + goto out; /* * ENODEV means that we didn't recognise the ioctl, or that we @@ -516,8 +520,12 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, ret = scsi_nonblockable_ioctl(sdev, cmd, argp, (mode & FMODE_NDELAY) != 0); if (ret != -ENODEV) - return ret; - return scsi_ioctl(sdev, cmd, argp); + goto out; + ret = scsi_ioctl(sdev, cmd, argp); + +out: + unlock_kernel(); + return ret; } static int sr_block_media_changed(struct gendisk *disk) @@ -531,7 +539,7 @@ static const struct block_device_operations sr_bdops = .owner = THIS_MODULE, .open = sr_block_open, .release = sr_block_release, - .locked_ioctl = sr_block_ioctl, + .ioctl = sr_block_ioctl, .media_changed = sr_block_media_changed, /* * No compat_ioctl for now because sr_block_ioctl never diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index baf5258f598..a8b05fc80c6 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1246,7 +1246,6 @@ static inline int blk_integrity_rq(struct request *rq) struct block_device_operations { int (*open) (struct block_device *, fmode_t); int (*release) (struct gendisk *, fmode_t); - int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*direct_access) (struct block_device *, sector_t, -- cgit v1.2.3-70-g09d2 From 6e9624b8caec290d28b4c6d9ec75749df6372b87 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 7 Aug 2010 18:25:34 +0200 Subject: block: push down BKL into .open and .release The open and release block_device_operations are currently called with the BKL held. In order to change that, we must first make sure that all drivers that currently rely on this have no regressions. This blindly pushes the BKL into all .open and .release operations for all block drivers to prepare for the next step. The drivers can subsequently replace the BKL with their own locks or remove it completely when it can be shown that it is not needed. The functions blkdev_get and blkdev_put are the only remaining users of the big kernel lock in the block layer, besides a few uses in the ioctl code, none of which need to serialize with blkdev_{get,put}. Most of these two functions is also under the protection of bdev->bd_mutex, including the actual calls to ->open and ->release, and the common code does not access any global data structures that need the BKL. Signed-off-by: Arnd Bergmann Acked-by: Christoph Hellwig Signed-off-by: Jens Axboe --- arch/um/drivers/ubd_kern.c | 7 ++++++- drivers/block/DAC960.c | 13 +++++++++---- drivers/block/amiflop.c | 12 ++++++++++-- drivers/block/aoe/aoeblk.c | 4 ++++ drivers/block/ataflop.c | 14 +++++++++++++- drivers/block/cciss.c | 23 ++++++++++++++++++++--- drivers/block/cpqarray.c | 22 +++++++++++++++++++--- drivers/block/drbd/drbd_main.c | 4 ++++ drivers/block/floppy.c | 5 +++++ drivers/block/loop.c | 5 +++++ drivers/block/paride/pcd.c | 10 +++++++++- drivers/block/paride/pd.c | 4 ++++ drivers/block/paride/pf.c | 20 +++++++++++++++----- drivers/block/pktcdvd.c | 5 +++++ drivers/block/swim.c | 15 ++++++++++++++- drivers/block/swim3.c | 15 ++++++++++++++- drivers/block/ub.c | 17 ++++++++++++++++- drivers/block/viodasd.c | 19 ++++++++++++++++++- drivers/block/xen-blkfront.c | 7 +++++++ drivers/block/xsysace.c | 6 ++++++ drivers/block/z2ram.c | 13 ++++++++++--- drivers/cdrom/gdrom.c | 8 +++++++- drivers/cdrom/viocd.c | 10 +++++++++- drivers/ide/ide-cd.c | 14 +++++++++----- drivers/ide/ide-gd.c | 17 ++++++++++++++++- drivers/ide/ide-tape.c | 9 ++++++++- drivers/md/dm.c | 7 +++++++ drivers/md/md.c | 6 ++++++ drivers/memstick/core/mspro_block.c | 9 ++++++++- drivers/message/i2o/i2o_block.c | 5 +++++ drivers/mmc/card/block.c | 5 +++++ drivers/mtd/mtd_blkdevs.c | 6 +++++- drivers/s390/block/dasd.c | 6 ++++++ drivers/s390/block/dcssblk.c | 5 +++++ drivers/s390/char/tape_block.c | 8 +++++++- drivers/scsi/sd.c | 5 +++++ drivers/scsi/sr.c | 7 ++++++- drivers/staging/hv/blkvsc_drv.c | 5 +++++ fs/block_dev.c | 10 ++-------- 39 files changed, 334 insertions(+), 48 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index da992a3ad6b..1bcd208c459 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -33,6 +33,7 @@ #include "linux/mm.h" #include "linux/slab.h" #include "linux/vmalloc.h" +#include "linux/smp_lock.h" #include "linux/blkpg.h" #include "linux/genhd.h" #include "linux/spinlock.h" @@ -1098,6 +1099,7 @@ static int ubd_open(struct block_device *bdev, fmode_t mode) struct ubd *ubd_dev = disk->private_data; int err = 0; + lock_kernel(); if(ubd_dev->count == 0){ err = ubd_open_dev(ubd_dev); if(err){ @@ -1115,7 +1117,8 @@ static int ubd_open(struct block_device *bdev, fmode_t mode) if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); err = -EROFS; }*/ - out: +out: + unlock_kernel(); return err; } @@ -1123,8 +1126,10 @@ static int ubd_release(struct gendisk *disk, fmode_t mode) { struct ubd *ubd_dev = disk->private_data; + lock_kernel(); if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); + unlock_kernel(); return 0; } diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index c5f22bb0a48..4e2c367fec1 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -79,23 +79,28 @@ static int DAC960_open(struct block_device *bdev, fmode_t mode) struct gendisk *disk = bdev->bd_disk; DAC960_Controller_T *p = disk->queue->queuedata; int drive_nr = (long)disk->private_data; + int ret = -ENXIO; + lock_kernel(); if (p->FirmwareType == DAC960_V1_Controller) { if (p->V1.LogicalDriveInformation[drive_nr]. LogicalDriveState == DAC960_V1_LogicalDrive_Offline) - return -ENXIO; + goto out; } else { DAC960_V2_LogicalDeviceInfo_T *i = p->V2.LogicalDeviceInformation[drive_nr]; if (!i || i->LogicalDeviceState == DAC960_V2_LogicalDevice_Offline) - return -ENXIO; + goto out; } check_disk_change(bdev); if (!get_capacity(p->disks[drive_nr])) - return -ENXIO; - return 0; + goto out; + ret = 0; +out: + unlock_kernel(); + return ret; } static int DAC960_getgeo(struct block_device *bdev, struct hd_geometry *geo) diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c index 0fa26359304..76f114f0bba 100644 --- a/drivers/block/amiflop.c +++ b/drivers/block/amiflop.c @@ -1555,10 +1555,13 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) int old_dev; unsigned long flags; + lock_kernel(); old_dev = fd_device[drive]; - if (fd_ref[drive] && old_dev != system) + if (fd_ref[drive] && old_dev != system) { + unlock_kernel(); return -EBUSY; + } if (mode & (FMODE_READ|FMODE_WRITE)) { check_disk_change(bdev); @@ -1571,8 +1574,10 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) fd_deselect (drive); rel_fdc(); - if (wrprot) + if (wrprot) { + unlock_kernel(); return -EROFS; + } } } @@ -1589,6 +1594,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) printk(KERN_INFO "fd%d: accessing %s-disk with %s-layout\n",drive, unit[drive].type->name, data_types[system].name); + unlock_kernel(); return 0; } @@ -1597,6 +1603,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) struct amiga_floppy_struct *p = disk->private_data; int drive = p - unit; + lock_kernel(); if (unit[drive].dirty == 1) { del_timer (flush_track_timer + drive); non_int_flush_track (drive); @@ -1610,6 +1617,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) /* the mod_use counter is handled this way */ floppy_off (drive | 0x40000000); #endif + unlock_kernel(); return 0; } diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 65deffde60a..a946929735a 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "aoe.h" static struct kmem_cache *buf_pool_cache; @@ -124,13 +125,16 @@ aoeblk_open(struct block_device *bdev, fmode_t mode) struct aoedev *d = bdev->bd_disk->private_data; ulong flags; + lock_kernel(); spin_lock_irqsave(&d->lock, flags); if (d->flags & DEVFL_UP) { d->nopen++; spin_unlock_irqrestore(&d->lock, flags); + unlock_kernel(); return 0; } spin_unlock_irqrestore(&d->lock, flags); + unlock_kernel(); return -ENODEV; } diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 1bb8bfcfdbd..aceb9647652 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c @@ -1850,22 +1850,34 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) return 0; } +static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = floppy_open(bdev, mode); + unlock_kernel(); + + return ret; +} static int floppy_release(struct gendisk *disk, fmode_t mode) { struct atari_floppy_struct *p = disk->private_data; + lock_kernel(); if (p->ref < 0) p->ref = 0; else if (!p->ref--) { printk(KERN_ERR "floppy_release with fd_ref == 0"); p->ref = 0; } + unlock_kernel(); return 0; } static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = fd_ioctl, .media_changed = check_floppy_change, diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index a6c0494dd05..665a470310a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -178,6 +178,7 @@ static void do_cciss_request(struct request_queue *q); static irqreturn_t do_cciss_intx(int irq, void *dev_id); static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id); static int cciss_open(struct block_device *bdev, fmode_t mode); +static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode); static int cciss_release(struct gendisk *disk, fmode_t mode); static int do_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); @@ -237,7 +238,7 @@ static int cciss_compat_ioctl(struct block_device *, fmode_t, static const struct block_device_operations cciss_fops = { .owner = THIS_MODULE, - .open = cciss_open, + .open = cciss_unlocked_open, .release = cciss_release, .ioctl = do_ioctl, .getgeo = cciss_getgeo, @@ -1042,13 +1043,28 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) return 0; } +static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = cciss_open(bdev, mode); + unlock_kernel(); + + return ret; +} + /* * Close. Sync first. */ static int cciss_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(disk); - drive_info_struct *drv = get_drv(disk); + ctlr_info_t *host; + drive_info_struct *drv; + + lock_kernel(); + host = get_host(disk); + drv = get_drv(disk); #ifdef CCISS_DEBUG printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); @@ -1056,6 +1072,7 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) drv->usage_count--; host->usage_count--; + unlock_kernel(); return 0; } diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index c459aeea3c0..28937b66156 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -158,7 +158,7 @@ static int sendcmd( unsigned int blkcnt, unsigned int log_unit ); -static int ida_open(struct block_device *bdev, fmode_t mode); +static int ida_unlocked_open(struct block_device *bdev, fmode_t mode); static int ida_release(struct gendisk *disk, fmode_t mode); static int ida_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); static int ida_getgeo(struct block_device *bdev, struct hd_geometry *geo); @@ -196,7 +196,7 @@ static inline ctlr_info_t *get_host(struct gendisk *disk) static const struct block_device_operations ida_fops = { .owner = THIS_MODULE, - .open = ida_open, + .open = ida_unlocked_open, .release = ida_release, .ioctl = ida_ioctl, .getgeo = ida_getgeo, @@ -841,13 +841,29 @@ static int ida_open(struct block_device *bdev, fmode_t mode) return 0; } +static int ida_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = ida_open(bdev, mode); + unlock_kernel(); + + return ret; +} + /* * Close. Sync first. */ static int ida_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host = get_host(disk); + ctlr_info_t *host; + + lock_kernel(); + host = get_host(disk); host->usage_count--; + unlock_kernel(); + return 0; } diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index e2ab13d99d6..d2b6764a7b1 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2604,6 +2604,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) unsigned long flags; int rv = 0; + lock_kernel(); spin_lock_irqsave(&mdev->req_lock, flags); /* to have a stable mdev->state.role * and no race with updating open_cnt */ @@ -2618,6 +2619,7 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) if (!rv) mdev->open_cnt++; spin_unlock_irqrestore(&mdev->req_lock, flags); + unlock_kernel(); return rv; } @@ -2625,7 +2627,9 @@ static int drbd_open(struct block_device *bdev, fmode_t mode) static int drbd_release(struct gendisk *gd, fmode_t mode) { struct drbd_conf *mdev = gd->private_data; + lock_kernel(); mdev->open_cnt--; + unlock_kernel(); return 0; } diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 40419b066aa..3126d5122b2 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -3616,6 +3616,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) { int drive = (long)disk->private_data; + lock_kernel(); mutex_lock(&open_lock); if (UDRS->fd_ref < 0) UDRS->fd_ref = 0; @@ -3626,6 +3627,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) if (!UDRS->fd_ref) opened_bdev[drive] = NULL; mutex_unlock(&open_lock); + unlock_kernel(); return 0; } @@ -3643,6 +3645,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) int res = -EBUSY; char *tmp; + lock_kernel(); mutex_lock(&open_lock); old_dev = UDRS->fd_device; if (opened_bdev[drive] && opened_bdev[drive] != bdev) @@ -3719,6 +3722,7 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) goto out; } mutex_unlock(&open_lock); + unlock_kernel(); return 0; out: if (UDRS->fd_ref < 0) @@ -3729,6 +3733,7 @@ out: opened_bdev[drive] = NULL; out2: mutex_unlock(&open_lock); + unlock_kernel(); return res; } diff --git a/drivers/block/loop.c b/drivers/block/loop.c index d285a548196..f3c636d2371 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -67,6 +67,7 @@ #include #include #include +#include #include #include /* for invalidate_bdev() */ #include @@ -1408,9 +1409,11 @@ static int lo_open(struct block_device *bdev, fmode_t mode) { struct loop_device *lo = bdev->bd_disk->private_data; + lock_kernel(); mutex_lock(&lo->lo_ctl_mutex); lo->lo_refcnt++; mutex_unlock(&lo->lo_ctl_mutex); + unlock_kernel(); return 0; } @@ -1420,6 +1423,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) struct loop_device *lo = disk->private_data; int err; + lock_kernel(); mutex_lock(&lo->lo_ctl_mutex); if (--lo->lo_refcnt) @@ -1444,6 +1448,7 @@ static int lo_release(struct gendisk *disk, fmode_t mode) out: mutex_unlock(&lo->lo_ctl_mutex); out_unlocked: + lock_kernel(); return 0; } diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c index daba7a62a66..76f8565e1e8 100644 --- a/drivers/block/paride/pcd.c +++ b/drivers/block/paride/pcd.c @@ -225,13 +225,21 @@ static char *pcd_buf; /* buffer for request in progress */ static int pcd_block_open(struct block_device *bdev, fmode_t mode) { struct pcd_unit *cd = bdev->bd_disk->private_data; - return cdrom_open(&cd->info, bdev, mode); + int ret; + + lock_kernel(); + ret = cdrom_open(&cd->info, bdev, mode); + unlock_kernel(); + + return ret; } static int pcd_block_release(struct gendisk *disk, fmode_t mode) { struct pcd_unit *cd = disk->private_data; + lock_kernel(); cdrom_release(&cd->info, mode); + unlock_kernel(); return 0; } diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index c4d6ed9846c..985f0d4f1d1 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -736,12 +736,14 @@ static int pd_open(struct block_device *bdev, fmode_t mode) { struct pd_unit *disk = bdev->bd_disk->private_data; + lock_kernel(); disk->access++; if (disk->removable) { pd_special_command(disk, pd_media_check); pd_special_command(disk, pd_door_lock); } + unlock_kernel(); return 0; } @@ -783,8 +785,10 @@ static int pd_release(struct gendisk *p, fmode_t mode) { struct pd_unit *disk = p->private_data; + lock_kernel(); if (!--disk->access && disk->removable) pd_special_command(disk, pd_door_unlock); + unlock_kernel(); return 0; } diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c index 38b4d566b81..4457b494882 100644 --- a/drivers/block/paride/pf.c +++ b/drivers/block/paride/pf.c @@ -300,20 +300,26 @@ static void __init pf_init_units(void) static int pf_open(struct block_device *bdev, fmode_t mode) { struct pf_unit *pf = bdev->bd_disk->private_data; + int ret; + lock_kernel(); pf_identify(pf); + ret = -ENODEV; if (pf->media_status == PF_NM) - return -ENODEV; + goto out; + ret = -EROFS; if ((pf->media_status == PF_RO) && (mode & FMODE_WRITE)) - return -EROFS; + goto out; + ret = 0; pf->access++; if (pf->removable) pf_lock(pf, 1); - - return 0; +out: + unlock_kernel(); + return ret; } static int pf_getgeo(struct block_device *bdev, struct hd_geometry *geo) @@ -354,14 +360,18 @@ static int pf_release(struct gendisk *disk, fmode_t mode) { struct pf_unit *pf = disk->private_data; - if (pf->access <= 0) + lock_kernel(); + if (pf->access <= 0) { + unlock_kernel(); return -EINVAL; + } pf->access--; if (!pf->access && pf->removable) pf_lock(pf, 0); + unlock_kernel(); return 0; } diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 40f1e31f42c..b1cbeb59bb7 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2383,6 +2383,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode) VPRINTK(DRIVER_NAME": entering open\n"); + lock_kernel(); mutex_lock(&ctl_mutex); pd = pkt_find_dev_from_minor(MINOR(bdev->bd_dev)); if (!pd) { @@ -2410,6 +2411,7 @@ static int pkt_open(struct block_device *bdev, fmode_t mode) } mutex_unlock(&ctl_mutex); + unlock_kernel(); return 0; out_dec: @@ -2417,6 +2419,7 @@ out_dec: out: VPRINTK(DRIVER_NAME": failed open (%d)\n", ret); mutex_unlock(&ctl_mutex); + unlock_kernel(); return ret; } @@ -2425,6 +2428,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode) struct pktcdvd_device *pd = disk->private_data; int ret = 0; + lock_kernel(); mutex_lock(&ctl_mutex); pd->refcnt--; BUG_ON(pd->refcnt < 0); @@ -2433,6 +2437,7 @@ static int pkt_close(struct gendisk *disk, fmode_t mode) pkt_release_dev(pd, flush); } mutex_unlock(&ctl_mutex); + unlock_kernel(); return ret; } diff --git a/drivers/block/swim.c b/drivers/block/swim.c index f04f74e3758..2e46815876d 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -662,11 +662,23 @@ out: return err; } +static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = floppy_open(bdev, mode); + unlock_kernel(); + + return ret; +} + static int floppy_release(struct gendisk *disk, fmode_t mode) { struct floppy_state *fs = disk->private_data; struct swim __iomem *base = fs->swd->base; + lock_kernel(); if (fs->ref_count < 0) fs->ref_count = 0; else if (fs->ref_count > 0) @@ -674,6 +686,7 @@ static int floppy_release(struct gendisk *disk, fmode_t mode) if (fs->ref_count == 0) swim_motor(base, OFF); + unlock_kernel(); return 0; } @@ -754,7 +767,7 @@ static int floppy_revalidate(struct gendisk *disk) static const struct block_device_operations floppy_fops = { .owner = THIS_MODULE, - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = floppy_ioctl, .getgeo = floppy_getgeo, diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index f3657b2a538..cc6a3864822 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -949,15 +949,28 @@ static int floppy_open(struct block_device *bdev, fmode_t mode) return 0; } +static int floppy_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = floppy_open(bdev, mode); + unlock_kernel(); + + return ret; +} + static int floppy_release(struct gendisk *disk, fmode_t mode) { struct floppy_state *fs = disk->private_data; struct swim3 __iomem *sw = fs->swim3; + lock_kernel(); if (fs->ref_count > 0 && --fs->ref_count == 0) { swim3_action(fs, MOTOR_OFF); out_8(&sw->control_bic, 0xff); swim3_select(fs, RELAX); } + unlock_kernel(); return 0; } @@ -1008,7 +1021,7 @@ static int floppy_revalidate(struct gendisk *disk) } static const struct block_device_operations floppy_fops = { - .open = floppy_open, + .open = floppy_unlocked_open, .release = floppy_release, .ioctl = floppy_ioctl, .media_changed = floppy_check_change, diff --git a/drivers/block/ub.c b/drivers/block/ub.c index 102ed52d0e0..c48e1487858 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -1711,6 +1711,18 @@ err_open: return rc; } +static int ub_bd_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = ub_bd_open(bdev, mode); + unlock_kernel(); + + return ret; +} + + /* */ static int ub_bd_release(struct gendisk *disk, fmode_t mode) @@ -1718,7 +1730,10 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode) struct ub_lun *lun = disk->private_data; struct ub_dev *sc = lun->udev; + lock_kernel(); ub_put(sc); + unlock_kernel(); + return 0; } @@ -1798,7 +1813,7 @@ static int ub_bd_media_changed(struct gendisk *disk) static const struct block_device_operations ub_bd_fops = { .owner = THIS_MODULE, - .open = ub_bd_open, + .open = ub_bd_unlocked_open, .release = ub_bd_release, .ioctl = ub_bd_ioctl, .media_changed = ub_bd_media_changed, diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index 5663d3c284c..f651e51a331 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -175,6 +176,18 @@ static int viodasd_open(struct block_device *bdev, fmode_t mode) return 0; } +static int viodasd_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = viodasd_open(bdev, mode); + unlock_kernel(); + + return ret; +} + + /* * External release entry point. */ @@ -183,6 +196,7 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) struct viodasd_device *d = disk->private_data; HvLpEvent_Rc hvrc; + lock_kernel(); /* Send the event to OS/400. We DON'T expect a response */ hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, HvLpEvent_Type_VirtualIo, @@ -195,6 +209,9 @@ static int viodasd_release(struct gendisk *disk, fmode_t mode) 0, 0, 0); if (hvrc != 0) pr_warning("HV close call failed %d\n", (int)hvrc); + + unlock_kernel(); + return 0; } @@ -219,7 +236,7 @@ static int viodasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) */ static const struct block_device_operations viodasd_fops = { .owner = THIS_MODULE, - .open = viodasd_open, + .open = viodasd_unlocked_open, .release = viodasd_release, .getgeo = viodasd_getgeo, }; diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 9119cd3d56a..91374282755 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -1018,13 +1019,18 @@ static int blkfront_is_ready(struct xenbus_device *dev) static int blkif_open(struct block_device *bdev, fmode_t mode) { struct blkfront_info *info = bdev->bd_disk->private_data; + + lock_kernel(); info->users++; + unlock_kernel(); + return 0; } static int blkif_release(struct gendisk *disk, fmode_t mode) { struct blkfront_info *info = disk->private_data; + lock_kernel(); info->users--; if (info->users == 0) { /* Check whether we have been instructed to close. We will @@ -1036,6 +1042,7 @@ static int blkif_release(struct gendisk *disk, fmode_t mode) if (state == XenbusStateClosing && info->is_ready) blkfront_closing(dev); } + unlock_kernel(); return 0; } diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index ac278ac908d..b71888b909a 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c @@ -89,6 +89,7 @@ #include #include #include +#include #include #include #include @@ -901,11 +902,14 @@ static int ace_open(struct block_device *bdev, fmode_t mode) dev_dbg(ace->dev, "ace_open() users=%i\n", ace->users + 1); + lock_kernel(); spin_lock_irqsave(&ace->lock, flags); ace->users++; spin_unlock_irqrestore(&ace->lock, flags); check_disk_change(bdev); + unlock_kernel(); + return 0; } @@ -917,6 +921,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode) dev_dbg(ace->dev, "ace_release() users=%i\n", ace->users - 1); + lock_kernel(); spin_lock_irqsave(&ace->lock, flags); ace->users--; if (ace->users == 0) { @@ -924,6 +929,7 @@ static int ace_release(struct gendisk *disk, fmode_t mode) ace_out(ace, ACE_CTRL, val & ~ACE_CTRL_LOCKREQ); } spin_unlock_irqrestore(&ace->lock, flags); + unlock_kernel(); return 0; } diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 9114654b54d..d75b2bb601a 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -153,6 +154,7 @@ static int z2_open(struct block_device *bdev, fmode_t mode) device = MINOR(bdev->bd_dev); + lock_kernel(); if ( current_device != -1 && current_device != device ) { rc = -EBUSY; @@ -294,20 +296,25 @@ static int z2_open(struct block_device *bdev, fmode_t mode) set_capacity(z2ram_gendisk, z2ram_size >> 9); } + unlock_kernel(); return 0; err_out_kfree: kfree(z2ram_map); err_out: + unlock_kernel(); return rc; } static int z2_release(struct gendisk *disk, fmode_t mode) { - if ( current_device == -1 ) - return 0; - + lock_kernel(); + if ( current_device == -1 ) { + unlock_kernel(); + return 0; + } + unlock_kernel(); /* * FIXME: unmap memory */ diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 1772fd914fb..261107d1457 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -493,12 +493,18 @@ static struct cdrom_device_ops gdrom_ops = { static int gdrom_bdops_open(struct block_device *bdev, fmode_t mode) { - return cdrom_open(gd.cd_info, bdev, mode); + int ret; + lock_kernel(); + ret = cdrom_open(gd.cd_info, bdev, mode); + unlock_kernel(); + return ret; } static int gdrom_bdops_release(struct gendisk *disk, fmode_t mode) { + lock_kernel(); cdrom_release(gd.cd_info, mode); + unlock_kernel(); return 0; } diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 16dada0627e..56bf9f44700 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -154,13 +154,21 @@ static const struct file_operations proc_viocd_operations = { static int viocd_blk_open(struct block_device *bdev, fmode_t mode) { struct disk_info *di = bdev->bd_disk->private_data; - return cdrom_open(&di->viocd_info, bdev, mode); + int ret; + + lock_kernel(); + ret = cdrom_open(&di->viocd_info, bdev, mode); + unlock_kernel(); + + return ret; } static int viocd_blk_release(struct gendisk *disk, fmode_t mode) { struct disk_info *di = disk->private_data; + lock_kernel(); cdrom_release(&di->viocd_info, mode); + unlock_kernel(); return 0; } diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index bf9f61a5c2f..5108e9739c9 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1591,17 +1591,19 @@ static struct ide_driver ide_cdrom_driver = { static int idecd_open(struct block_device *bdev, fmode_t mode) { - struct cdrom_info *info = ide_cd_get(bdev->bd_disk); - int rc = -ENOMEM; + struct cdrom_info *info; + int rc = -ENXIO; + lock_kernel(); + info = ide_cd_get(bdev->bd_disk); if (!info) - return -ENXIO; + goto out; rc = cdrom_open(&info->devinfo, bdev, mode); - if (rc < 0) ide_cd_put(info); - +out: + unlock_kernel(); return rc; } @@ -1609,9 +1611,11 @@ static int idecd_release(struct gendisk *disk, fmode_t mode) { struct cdrom_info *info = ide_drv_g(disk, cdrom_info); + lock_kernel(); cdrom_release(&info->devinfo, mode); ide_cd_put(info); + unlock_kernel(); return 0; } diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index 883f0c979c9..137337a795a 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -237,6 +238,18 @@ out_put_idkp: return ret; } +static int ide_gd_unlocked_open(struct block_device *bdev, fmode_t mode) +{ + int ret; + + lock_kernel(); + ret = ide_gd_open(bdev, mode); + unlock_kernel(); + + return ret; +} + + static int ide_gd_release(struct gendisk *disk, fmode_t mode) { struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj); @@ -244,6 +257,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) ide_debug_log(IDE_DBG_FUNC, "enter"); + lock_kernel(); if (idkp->openers == 1) drive->disk_ops->flush(drive); @@ -255,6 +269,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode) idkp->openers--; ide_disk_put(idkp); + unlock_kernel(); return 0; } @@ -321,7 +336,7 @@ static int ide_gd_ioctl(struct block_device *bdev, fmode_t mode, static const struct block_device_operations ide_gd_ops = { .owner = THIS_MODULE, - .open = ide_gd_open, + .open = ide_gd_unlocked_open, .release = ide_gd_release, .ioctl = ide_gd_ioctl, .getgeo = ide_gd_getgeo, diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 39b0a5c45f0..6d622cb5ac8 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1907,7 +1907,11 @@ static const struct file_operations idetape_fops = { static int idetape_open(struct block_device *bdev, fmode_t mode) { - struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk, false, 0); + struct ide_tape_obj *tape; + + lock_kernel(); + tape = ide_tape_get(bdev->bd_disk, false, 0); + unlock_kernel(); if (!tape) return -ENXIO; @@ -1919,7 +1923,10 @@ static int idetape_release(struct gendisk *disk, fmode_t mode) { struct ide_tape_obj *tape = ide_drv_g(disk, ide_tape_obj); + lock_kernel(); ide_tape_put(tape); + unlock_kernel(); + return 0; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index d505a96845c..a3f21dc02bd 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -338,6 +339,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) { struct mapped_device *md; + lock_kernel(); spin_lock(&_minor_lock); md = bdev->bd_disk->private_data; @@ -355,6 +357,7 @@ static int dm_blk_open(struct block_device *bdev, fmode_t mode) out: spin_unlock(&_minor_lock); + unlock_kernel(); return md ? 0 : -ENXIO; } @@ -362,8 +365,12 @@ out: static int dm_blk_close(struct gendisk *disk, fmode_t mode) { struct mapped_device *md = disk->private_data; + + lock_kernel(); atomic_dec(&md->open_count); dm_put(md); + unlock_kernel(); + return 0; } diff --git a/drivers/md/md.c b/drivers/md/md.c index 1893af67877..700c96edf9b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* for invalidate_bdev */ #include #include @@ -5902,6 +5903,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) mddev_t *mddev = mddev_find(bdev->bd_dev); int err; + lock_kernel(); if (mddev->gendisk != bdev->bd_disk) { /* we are racing with mddev_put which is discarding this * bd_disk. @@ -5910,6 +5912,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) /* Wait until bdev->bd_disk is definitely gone */ flush_scheduled_work(); /* Then retry the open from the top */ + unlock_kernel(); return -ERESTARTSYS; } BUG_ON(mddev != bdev->bd_disk->private_data); @@ -5923,6 +5926,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) check_disk_size_change(mddev->gendisk, bdev); out: + unlock_kernel(); return err; } @@ -5931,8 +5935,10 @@ static int md_release(struct gendisk *disk, fmode_t mode) mddev_t *mddev = disk->private_data; BUG_ON(!mddev); + lock_kernel(); atomic_dec(&mddev->openers); mddev_put(mddev); + unlock_kernel(); return 0; } diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 56645408d22..eef78a068fd 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #define DRIVER_NAME "mspro_block" @@ -179,6 +180,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) struct mspro_block_data *msb = disk->private_data; int rc = -ENXIO; + lock_kernel(); mutex_lock(&mspro_block_disk_lock); if (msb && msb->card) { @@ -190,6 +192,7 @@ static int mspro_block_bd_open(struct block_device *bdev, fmode_t mode) } mutex_unlock(&mspro_block_disk_lock); + unlock_kernel(); return rc; } @@ -221,7 +224,11 @@ static int mspro_block_disk_release(struct gendisk *disk) static int mspro_block_bd_release(struct gendisk *disk, fmode_t mode) { - return mspro_block_disk_release(disk); + int ret; + lock_kernel(); + ret = mspro_block_disk_release(disk); + unlock_kernel(); + return ret; } static int mspro_block_bd_getgeo(struct block_device *bdev, diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index d1bdf8abe5d..a5bc3ee0d93 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -53,6 +53,7 @@ #include #include #include +#include #include @@ -577,6 +578,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) if (!dev->i2o_dev) return -ENODEV; + lock_kernel(); if (dev->power > 0x1f) i2o_block_device_power(dev, 0x02); @@ -585,6 +587,7 @@ static int i2o_block_open(struct block_device *bdev, fmode_t mode) i2o_block_device_lock(dev->i2o_dev, -1); osm_debug("Ready.\n"); + unlock_kernel(); return 0; }; @@ -615,6 +618,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) if (!dev->i2o_dev) return 0; + lock_kernel(); i2o_block_device_flush(dev->i2o_dev); i2o_block_device_unlock(dev->i2o_dev, -1); @@ -625,6 +629,7 @@ static int i2o_block_release(struct gendisk *disk, fmode_t mode) operation = 0x24; i2o_block_device_power(dev, operation); + unlock_kernel(); return 0; } diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index cb9fbc83b09..8433cde29c8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -107,6 +108,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk); int ret = -ENXIO; + lock_kernel(); if (md) { if (md->usage == 2) check_disk_change(bdev); @@ -117,6 +119,7 @@ static int mmc_blk_open(struct block_device *bdev, fmode_t mode) ret = -EROFS; } } + unlock_kernel(); return ret; } @@ -125,7 +128,9 @@ static int mmc_blk_release(struct gendisk *disk, fmode_t mode) { struct mmc_blk_data *md = disk->private_data; + lock_kernel(); mmc_blk_put(md); + unlock_kernel(); return 0; } diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 8c83b11a77d..5ca80aee2ed 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -165,8 +165,9 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) int ret; if (!dev) - return -ERESTARTSYS; + return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/ + lock_kernel(); mutex_lock(&dev->lock); if (!dev->mtd) { @@ -183,6 +184,7 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) unlock: mutex_unlock(&dev->lock); blktrans_dev_put(dev); + unlock_kernel(); return ret; } @@ -194,6 +196,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode) if (!dev) return ret; + lock_kernel(); mutex_lock(&dev->lock); /* Release one reference, we sure its not the last one here*/ @@ -206,6 +209,7 @@ static int blktrans_release(struct gendisk *disk, fmode_t mode) unlock: mutex_unlock(&dev->lock); blktrans_dev_put(dev); + unlock_kernel(); return ret; } diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 17b033d0e05..1a84fae155e 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2235,6 +2236,7 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) if (!block) return -ENODEV; + lock_kernel(); base = block->base; atomic_inc(&block->open_count); if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { @@ -2269,12 +2271,14 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) goto out; } + unlock_kernel(); return 0; out: module_put(base->discipline->owner); unlock: atomic_dec(&block->open_count); + unlock_kernel(); return rc; } @@ -2282,8 +2286,10 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) { struct dasd_block *block = disk->private_data; + lock_kernel(); atomic_dec(&block->open_count); module_put(block->base->discipline->owner); + unlock_kernel(); return 0; } diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 9b43ae94beb..2bd72aa34c5 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -775,6 +776,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode) struct dcssblk_dev_info *dev_info; int rc; + lock_kernel(); dev_info = bdev->bd_disk->private_data; if (NULL == dev_info) { rc = -ENODEV; @@ -784,6 +786,7 @@ dcssblk_open(struct block_device *bdev, fmode_t mode) bdev->bd_block_size = 4096; rc = 0; out: + unlock_kernel(); return rc; } @@ -794,6 +797,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) struct segment_info *entry; int rc; + lock_kernel(); if (!dev_info) { rc = -ENODEV; goto out; @@ -811,6 +815,7 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) up_write(&dcssblk_devices_sem); rc = 0; out: + unlock_kernel(); return rc; } diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 097da8ce6be..b7de02525ec 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -361,6 +362,7 @@ tapeblock_open(struct block_device *bdev, fmode_t mode) struct tape_device * device; int rc; + lock_kernel(); device = tape_get_device(disk->private_data); if (device->required_tapemarks) { @@ -384,12 +386,14 @@ tapeblock_open(struct block_device *bdev, fmode_t mode) * is called. */ tape_state_set(device, TS_BLKUSE); + unlock_kernel(); return 0; release: tape_release(device); put_device: tape_put_device(device); + unlock_kernel(); return rc; } @@ -403,10 +407,12 @@ static int tapeblock_release(struct gendisk *disk, fmode_t mode) { struct tape_device *device = disk->private_data; - + + lock_kernel(); tape_state_set(device, TS_IN_USE); tape_release(device); tape_put_device(device); + unlock_kernel(); return 0; } diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 633ac32b25c..01680c7c850 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -795,6 +795,7 @@ static int sd_open(struct block_device *bdev, fmode_t mode) SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n")); + lock_kernel(); sdev = sdkp->device; /* @@ -838,10 +839,12 @@ static int sd_open(struct block_device *bdev, fmode_t mode) scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT); } + unlock_kernel(); return 0; error_out: scsi_disk_put(sdkp); + unlock_kernel(); return retval; } @@ -863,6 +866,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode) SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n")); + lock_kernel(); if (!--sdkp->openers && sdev->removable) { if (scsi_block_when_processing_errors(sdev)) scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW); @@ -873,6 +877,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode) * XXX is followed by a "rmmod sd_mod"? */ scsi_disk_put(sdkp); + unlock_kernel(); return 0; } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d42fa6468f4..ba9c3e0387c 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -467,22 +467,27 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) static int sr_block_open(struct block_device *bdev, fmode_t mode) { - struct scsi_cd *cd = scsi_cd_get(bdev->bd_disk); + struct scsi_cd *cd; int ret = -ENXIO; + lock_kernel(); + cd = scsi_cd_get(bdev->bd_disk); if (cd) { ret = cdrom_open(&cd->cdi, bdev, mode); if (ret) scsi_cd_put(cd); } + unlock_kernel(); return ret; } static int sr_block_release(struct gendisk *disk, fmode_t mode) { struct scsi_cd *cd = scsi_cd(disk); + lock_kernel(); cdrom_release(&cd->cdi, mode); scsi_cd_put(cd); + unlock_kernel(); return 0; } diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index a9aff90e58e..87a11c9293e 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1326,6 +1327,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode) DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users, blkdev->gd->disk_name); + lock_kernel(); spin_lock(&blkdev->lock); if (!blkdev->users && blkdev->device_type == DVD_TYPE) { @@ -1337,6 +1339,7 @@ static int blkvsc_open(struct block_device *bdev, fmode_t mode) blkdev->users++; spin_unlock(&blkdev->lock); + unlock_kernel(); return 0; } @@ -1347,6 +1350,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users, blkdev->gd->disk_name); + lock_kernel(); spin_lock(&blkdev->lock); if (blkdev->users == 1) { spin_unlock(&blkdev->lock); @@ -1357,6 +1361,7 @@ static int blkvsc_release(struct gendisk *disk, fmode_t mode) blkdev->users--; spin_unlock(&blkdev->lock); + unlock_kernel(); return 0; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 99d6af81174..693c2bf5d65 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1345,13 +1345,12 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) return ret; } - lock_kernel(); restart: ret = -ENXIO; disk = get_gendisk(bdev->bd_dev, &partno); if (!disk) - goto out_unlock_kernel; + goto out; mutex_lock_nested(&bdev->bd_mutex, for_part); if (!bdev->bd_openers) { @@ -1431,7 +1430,6 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) if (for_part) bdev->bd_part_count++; mutex_unlock(&bdev->bd_mutex); - unlock_kernel(); return 0; out_clear: @@ -1444,9 +1442,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) bdev->bd_contains = NULL; out_unlock_bdev: mutex_unlock(&bdev->bd_mutex); - out_unlock_kernel: - unlock_kernel(); - + out: if (disk) module_put(disk->fops->owner); put_disk(disk); @@ -1515,7 +1511,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) struct block_device *victim = NULL; mutex_lock_nested(&bdev->bd_mutex, for_part); - lock_kernel(); if (for_part) bdev->bd_part_count--; @@ -1540,7 +1535,6 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) victim = bdev->bd_contains; bdev->bd_contains = NULL; } - unlock_kernel(); mutex_unlock(&bdev->bd_mutex); bdput(bdev); if (victim) -- cgit v1.2.3-70-g09d2 From 292e50dd393a8359798f1f20ac4d48ec835ffa04 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:44:50 -0500 Subject: cciss: save pdev pointer in per hba structure early to avoid passing it around so much. cciss: save pdev pointer in per hba structure early to avoid passing it around so much. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 61 ++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 665a470310a..b79ce8e960f 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -199,8 +199,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, sector_t total_size, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv); -static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, - __u32); +static void __devinit cciss_interrupt_mode(ctlr_info_t *, __u32); static void start_io(ctlr_info_t *h); static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, __u8 page_code, unsigned char scsi3addr[], @@ -3933,8 +3932,7 @@ clean_up: * controllers that are capable. If not, we use IO-APIC mode. */ -static void __devinit cciss_interrupt_mode(ctlr_info_t *c, - struct pci_dev *pdev, __u32 board_id) +static void __devinit cciss_interrupt_mode(ctlr_info_t *c, __u32 board_id) { #ifdef CONFIG_PCI_MSI int err; @@ -3948,8 +3946,8 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, (board_id == 0x40820E11) || (board_id == 0x40830E11)) goto default_int_mode; - if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { - err = pci_enable_msix(pdev, cciss_msix_entries, 4); + if (pci_find_capability(c->pdev, PCI_CAP_ID_MSIX)) { + err = pci_enable_msix(c->pdev, cciss_msix_entries, 4); if (!err) { c->intr[0] = cciss_msix_entries[0].vector; c->intr[1] = cciss_msix_entries[1].vector; @@ -3968,8 +3966,8 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, goto default_int_mode; } } - if (pci_find_capability(pdev, PCI_CAP_ID_MSI)) { - if (!pci_enable_msi(pdev)) { + if (pci_find_capability(c->pdev, PCI_CAP_ID_MSI)) { + if (!pci_enable_msi(c->pdev)) { c->msi_vector = 1; } else { printk(KERN_WARNING "cciss: MSI init failed\n"); @@ -3978,11 +3976,11 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, default_int_mode: #endif /* CONFIG_PCI_MSI */ /* if we get here we're going to use the default interrupt mode */ - c->intr[PERF_MODE_INT] = pdev->irq; + c->intr[PERF_MODE_INT] = c->pdev->irq; return; } -static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) +static int __devinit cciss_pci_init(ctlr_info_t *c) { ushort subsystem_vendor_id, subsystem_device_id, command; __u32 board_id, scratchpad = 0; @@ -3992,8 +3990,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) int i, prod_index, err; __u32 trans_offset; - subsystem_vendor_id = pdev->subsystem_vendor; - subsystem_device_id = pdev->subsystem_device; + subsystem_vendor_id = c->pdev->subsystem_vendor; + subsystem_device_id = c->pdev->subsystem_device; board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | subsystem_vendor_id); @@ -4006,7 +4004,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) } prod_index = i; if (prod_index == ARRAY_SIZE(products)) { - dev_warn(&pdev->dev, + dev_warn(&c->pdev->dev, "unrecognized board ID: 0x%08lx, ignoring.\n", (unsigned long) board_id); return -ENODEV; @@ -4014,20 +4012,20 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) /* check to see if controller has been disabled */ /* BEFORE trying to enable it */ - (void)pci_read_config_word(pdev, PCI_COMMAND, &command); + (void)pci_read_config_word(c->pdev, PCI_COMMAND, &command); if (!(command & 0x02)) { printk(KERN_WARNING "cciss: controller appears to be disabled\n"); return -ENODEV; } - err = pci_enable_device(pdev); + err = pci_enable_device(c->pdev); if (err) { printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); return err; } - err = pci_request_regions(pdev, "cciss"); + err = pci_request_regions(c->pdev, "cciss"); if (err) { printk(KERN_ERR "cciss: Cannot obtain PCI resources, " "aborting\n"); @@ -4035,19 +4033,19 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) } #ifdef CCISS_DEBUG - printk("command = %x\n", command); - printk("irq = %x\n", pdev->irq); - printk("board_id = %x\n", board_id); + printk(KERN_INFO "command = %x\n", command); + printk(KERN_INFO "irq = %x\n", c->pdev->irq); + printk(KERN_INFO "board_id = %x\n", board_id); #endif /* CCISS_DEBUG */ /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. */ - cciss_interrupt_mode(c, pdev, board_id); + cciss_interrupt_mode(c, board_id); /* find the memory BAR */ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) + if (pci_resource_flags(c->pdev, i) & IORESOURCE_MEM) break; } if (i == DEVICE_COUNT_RESOURCE) { @@ -4056,7 +4054,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) goto err_out_free_res; } - c->paddr = pci_resource_start(pdev, i); /* addressing mode bits + c->paddr = pci_resource_start(c->pdev, i); /* addressing mode bits * already removed */ @@ -4086,7 +4084,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) #ifdef CCISS_DEBUG printk("cfg base address = %x\n", cfg_base_addr); #endif /* CCISS_DEBUG */ - cfg_base_addr_index = find_PCI_BAR_index(pdev, cfg_base_addr); + cfg_base_addr_index = find_PCI_BAR_index(c->pdev, cfg_base_addr); #ifdef CCISS_DEBUG printk("cfg base address index = %llx\n", (unsigned long long)cfg_base_addr_index); @@ -4101,12 +4099,12 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) #ifdef CCISS_DEBUG printk("cfg offset = %llx\n", (unsigned long long)cfg_offset); #endif /* CCISS_DEBUG */ - c->cfgtable = remap_pci_mem(pci_resource_start(pdev, + c->cfgtable = remap_pci_mem(pci_resource_start(c->pdev, cfg_base_addr_index) + cfg_offset, sizeof(CfgTable_struct)); /* Find performant mode table. */ trans_offset = readl(&(c->cfgtable->TransMethodOffset)); - c->transtable = remap_pci_mem(pci_resource_start(pdev, + c->transtable = remap_pci_mem(pci_resource_start(c->pdev, cfg_base_addr_index) + cfg_offset+trans_offset, sizeof(*c->transtable)); c->board_id = board_id; @@ -4173,9 +4171,11 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); dma_prefetch |= 0x8000; writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG); - pci_read_config_dword(pdev, PCI_COMMAND_PARITY, &dma_refetch); + pci_read_config_dword(c->pdev, PCI_COMMAND_PARITY, + &dma_refetch); dma_refetch |= 0x1; - pci_write_config_dword(pdev, PCI_COMMAND_PARITY, dma_refetch); + pci_write_config_dword(c->pdev, PCI_COMMAND_PARITY, + dma_refetch); } #ifdef CCISS_DEBUG @@ -4189,7 +4189,7 @@ err_out_free_res: * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo */ - pci_release_regions(pdev); + pci_release_regions(c->pdev); return err; } @@ -4466,17 +4466,18 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, i = alloc_cciss_hba(); if (i < 0) return -1; + + hba[i]->pdev = pdev; hba[i]->busy_initializing = 1; INIT_HLIST_HEAD(&hba[i]->cmpQ); INIT_HLIST_HEAD(&hba[i]->reqQ); mutex_init(&hba[i]->busy_shutting_down); - if (cciss_pci_init(hba[i], pdev) != 0) + if (cciss_pci_init(hba[i]) != 0) goto clean_no_release_regions; sprintf(hba[i]->devname, "cciss%d", i); hba[i]->ctlr = i; - hba[i]->pdev = pdev; init_completion(&hba[i]->scan_wait); -- cgit v1.2.3-70-g09d2 From 6539fa9b2e2e7fc3b3fe819e54aa7be83f0370fa Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:44:55 -0500 Subject: cciss: factor out cciss_lookup_board_id cciss: factor out cciss_lookup_board_id Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 66 +++++++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b79ce8e960f..d4167c29213 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3980,35 +3980,43 @@ default_int_mode: return; } -static int __devinit cciss_pci_init(ctlr_info_t *c) +static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) { - ushort subsystem_vendor_id, subsystem_device_id, command; - __u32 board_id, scratchpad = 0; - __u64 cfg_offset; - __u32 cfg_base_addr; - __u64 cfg_base_addr_index; - int i, prod_index, err; - __u32 trans_offset; + int i; + u32 subsystem_vendor_id, subsystem_device_id; - subsystem_vendor_id = c->pdev->subsystem_vendor; - subsystem_device_id = c->pdev->subsystem_device; - board_id = (((__u32) (subsystem_device_id << 16) & 0xffff0000) | - subsystem_vendor_id); + subsystem_vendor_id = pdev->subsystem_vendor; + subsystem_device_id = pdev->subsystem_device; + *board_id = ((subsystem_device_id << 16) & 0xffff0000) | + subsystem_vendor_id; for (i = 0; i < ARRAY_SIZE(products); i++) { /* Stand aside for hpsa driver on request */ if (cciss_allow_hpsa && products[i].board_id == HPSA_BOUNDARY) return -ENODEV; - if (board_id == products[i].board_id) - break; + if (*board_id == products[i].board_id) + return i; } - prod_index = i; - if (prod_index == ARRAY_SIZE(products)) { - dev_warn(&c->pdev->dev, - "unrecognized board ID: 0x%08lx, ignoring.\n", - (unsigned long) board_id); + dev_warn(&pdev->dev, "unrecognized board ID: 0x%08x, ignoring.\n", + *board_id); + return -ENODEV; +} + +static int __devinit cciss_pci_init(ctlr_info_t *c) +{ + ushort command; + __u32 scratchpad = 0; + __u64 cfg_offset; + __u32 cfg_base_addr; + __u64 cfg_base_addr_index; + __u32 trans_offset; + int i, prod_index, err; + + prod_index = cciss_lookup_board_id(c->pdev, &c->board_id); + if (prod_index < 0) return -ENODEV; - } + c->product_name = products[prod_index].product_name; + c->access = *(products[prod_index].access); /* check to see if controller has been disabled */ /* BEFORE trying to enable it */ @@ -4035,13 +4043,13 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) #ifdef CCISS_DEBUG printk(KERN_INFO "command = %x\n", command); printk(KERN_INFO "irq = %x\n", c->pdev->irq); - printk(KERN_INFO "board_id = %x\n", board_id); + printk(KERN_INFO "board_id = %x\n", c->board_id); #endif /* CCISS_DEBUG */ /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. */ - cciss_interrupt_mode(c, board_id); + cciss_interrupt_mode(c, c->board_id); /* find the memory BAR */ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { @@ -4107,11 +4115,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) c->transtable = remap_pci_mem(pci_resource_start(c->pdev, cfg_base_addr_index) + cfg_offset+trans_offset, sizeof(*c->transtable)); - c->board_id = board_id; - - #ifdef CCISS_DEBUG - print_cfg_table(c->cfgtable); - #endif /* CCISS_DEBUG */ +#ifdef CCISS_DEBUG + print_cfg_table(c->cfgtable); +#endif /* CCISS_DEBUG */ /* Some controllers support Zero Memory Raid (ZMR). * When configured in ZMR mode the number of supported @@ -4139,8 +4145,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) c->chainsize = 0; /* traditional */ } - c->product_name = products[prod_index].product_name; - c->access = *(products[prod_index].access); c->nr_cmds = c->max_commands - 4; if ((readb(&c->cfgtable->Signature[0]) != 'C') || (readb(&c->cfgtable->Signature[1]) != 'I') || @@ -4165,8 +4169,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) * We've disabled prefetch for some time now. Testing with XEN * kernels revealed a bug in the refetch if dom0 resides on a P600. */ - if(board_id == 0x3225103C) { - __u32 dma_prefetch; + if (c->board_id == 0x3225103C) { + __u32 dma_prefetch; __u32 dma_refetch; dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); dma_prefetch |= 0x8000; -- cgit v1.2.3-70-g09d2 From dd9c426e92d0cbd710c8df5b84afe9a2eeda3918 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:00 -0500 Subject: cciss: factor out cciss_board_disabled cciss: factor out cciss_board_disabled Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index d4167c29213..808d2a5b46b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4002,9 +4002,16 @@ static int __devinit cciss_lookup_board_id(struct pci_dev *pdev, u32 *board_id) return -ENODEV; } +static inline bool cciss_board_disabled(ctlr_info_t *h) +{ + u16 command; + + (void) pci_read_config_word(h->pdev, PCI_COMMAND, &command); + return ((command & PCI_COMMAND_MEMORY) == 0); +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { - ushort command; __u32 scratchpad = 0; __u64 cfg_offset; __u32 cfg_base_addr; @@ -4018,15 +4025,11 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) c->product_name = products[prod_index].product_name; c->access = *(products[prod_index].access); - /* check to see if controller has been disabled */ - /* BEFORE trying to enable it */ - (void)pci_read_config_word(c->pdev, PCI_COMMAND, &command); - if (!(command & 0x02)) { + if (cciss_board_disabled(c)) { printk(KERN_WARNING "cciss: controller appears to be disabled\n"); return -ENODEV; } - err = pci_enable_device(c->pdev); if (err) { printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); -- cgit v1.2.3-70-g09d2 From dac5488a9ed6b6e59749e161209a6678980803f1 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:05 -0500 Subject: cciss: remove board_id parameter from cciss_interrupt_mode() cciss: remove board_id parameter from cciss_interrupt_mode() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 808d2a5b46b..bb22a80d448 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -199,7 +199,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, sector_t total_size, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv); -static void __devinit cciss_interrupt_mode(ctlr_info_t *, __u32); +static void __devinit cciss_interrupt_mode(ctlr_info_t *); static void start_io(ctlr_info_t *h); static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, __u8 page_code, unsigned char scsi3addr[], @@ -3932,7 +3932,7 @@ clean_up: * controllers that are capable. If not, we use IO-APIC mode. */ -static void __devinit cciss_interrupt_mode(ctlr_info_t *c, __u32 board_id) +static void __devinit cciss_interrupt_mode(ctlr_info_t *c) { #ifdef CONFIG_PCI_MSI int err; @@ -3941,9 +3941,8 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c, __u32 board_id) }; /* Some boards advertise MSI but don't really support it */ - if ((board_id == 0x40700E11) || - (board_id == 0x40800E11) || - (board_id == 0x40820E11) || (board_id == 0x40830E11)) + if ((c->board_id == 0x40700E11) || (c->board_id == 0x40800E11) || + (c->board_id == 0x40820E11) || (c->board_id == 0x40830E11)) goto default_int_mode; if (pci_find_capability(c->pdev, PCI_CAP_ID_MSIX)) { @@ -4052,7 +4051,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. */ - cciss_interrupt_mode(c, c->board_id); + cciss_interrupt_mode(c); /* find the memory BAR */ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -- cgit v1.2.3-70-g09d2 From d474830da6218c0b7f81eab03aff7d8c539bdb57 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:10 -0500 Subject: cciss: factor out cciss_find_memory_BAR() cciss: factor out cciss_find_memory_BAR() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index bb22a80d448..9c9c79c0aa9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4009,6 +4009,23 @@ static inline bool cciss_board_disabled(ctlr_info_t *h) return ((command & PCI_COMMAND_MEMORY) == 0); } +static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, + unsigned long *memory_bar) +{ + int i; + + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) + if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { + /* addressing mode bits already removed */ + *memory_bar = pci_resource_start(pdev, i); + dev_dbg(&pdev->dev, "memory BAR = %lx\n", + *memory_bar); + return 0; + } + dev_warn(&pdev->dev, "no memory BAR found\n"); + return -ENODEV; +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { __u32 scratchpad = 0; @@ -4052,25 +4069,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) * else we use the IO-APIC interrupt assigned to us by system ROM. */ cciss_interrupt_mode(c); - - /* find the memory BAR */ - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - if (pci_resource_flags(c->pdev, i) & IORESOURCE_MEM) - break; - } - if (i == DEVICE_COUNT_RESOURCE) { - printk(KERN_WARNING "cciss: No memory BAR found\n"); - err = -ENODEV; + err = cciss_pci_find_memory_BAR(c->pdev, &c->paddr); + if (err) goto err_out_free_res; - } - - c->paddr = pci_resource_start(c->pdev, i); /* addressing mode bits - * already removed - */ - -#ifdef CCISS_DEBUG - printk("address 0 = %lx\n", c->paddr); -#endif /* CCISS_DEBUG */ c->vaddr = remap_pci_mem(c->paddr, 0x250); /* Wait for the board to become ready. (PCI hotplug needs this.) -- cgit v1.2.3-70-g09d2 From e99ba1362723df14bbe36da6eeaadf81d95782e6 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:15 -0500 Subject: cciss: factor out cciss_wait_for_board_ready() cciss: factor out cciss_wait_for_board_ready() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 32 +++++++++++++++++--------------- drivers/block/cciss.h | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 15 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9c9c79c0aa9..286c81d7081 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4026,9 +4026,23 @@ static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, return -ENODEV; } +static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) +{ + int i; + u32 scratchpad; + + for (i = 0; i < CCISS_BOARD_READY_ITERATIONS; i++) { + scratchpad = readl(h->vaddr + SA5_SCRATCHPAD_OFFSET); + if (scratchpad == CCISS_FIRMWARE_READY) + return 0; + msleep(CCISS_BOARD_READY_POLL_INTERVAL_MSECS); + } + dev_warn(&h->pdev->dev, "board not ready, timed out.\n"); + return -ENODEV; +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { - __u32 scratchpad = 0; __u64 cfg_offset; __u32 cfg_base_addr; __u64 cfg_base_addr_index; @@ -4073,21 +4087,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) if (err) goto err_out_free_res; c->vaddr = remap_pci_mem(c->paddr, 0x250); - - /* Wait for the board to become ready. (PCI hotplug needs this.) - * We poll for up to 120 secs, once per 100ms. */ - for (i = 0; i < 1200; i++) { - scratchpad = readl(c->vaddr + SA5_SCRATCHPAD_OFFSET); - if (scratchpad == CCISS_FIRMWARE_READY) - break; - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(msecs_to_jiffies(100)); /* wait 100ms */ - } - if (scratchpad != CCISS_FIRMWARE_READY) { - printk(KERN_WARNING "cciss: Board not ready. Timed out.\n"); - err = -ENODEV; + err = cciss_wait_for_board_ready(c); + if (err) goto err_out_free_res; - } /* get the address index number */ cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET); diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 8a9f5b58daa..c2ef9dd56c4 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -190,6 +190,21 @@ struct ctlr_info #define CCISS_INTR_ON 1 #define CCISS_INTR_OFF 0 + + +/* CCISS_BOARD_READY_WAIT_SECS is how long to wait for a board + * to become ready, in seconds, before giving up on it. + * CCISS_BOARD_READY_POLL_INTERVAL_MSECS * is how long to wait + * between polling the board to see if it is ready, in + * milliseconds. CCISS_BOARD_READY_ITERATIONS is derived + * the above. + */ +#define CCISS_BOARD_READY_WAIT_SECS (120) +#define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100) +#define CCISS_BOARD_READY_ITERATIONS \ + ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ + CCISS_BOARD_READY_POLL_INTERVAL_MSECS) + /* Send the command to the hardware */ -- cgit v1.2.3-70-g09d2 From 4809d0988f10e305511d1a3e223880fa4b21f90e Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:21 -0500 Subject: cciss: factor out cciss_find_cfgtables cciss: factor out cciss_find_cfgtables Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 68 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 286c81d7081..c297d31d0c9 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4041,13 +4041,40 @@ static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) return -ENODEV; } +static int __devinit cciss_find_cfgtables(ctlr_info_t *h) +{ + u64 cfg_offset; + u32 cfg_base_addr; + u64 cfg_base_addr_index; + u32 trans_offset; + + /* get the address index number */ + cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET); + cfg_base_addr &= (u32) 0x0000ffff; + cfg_base_addr_index = find_PCI_BAR_index(h->pdev, cfg_base_addr); + if (cfg_base_addr_index == -1) { + dev_warn(&h->pdev->dev, "cannot find cfg_base_addr_index\n"); + return -ENODEV; + } + cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET); + h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev, + cfg_base_addr_index) + cfg_offset, + sizeof(h->cfgtable)); + if (!h->cfgtable) + return -ENOMEM; + /* Find performant mode table. */ + trans_offset = readl(&(h->cfgtable->TransMethodOffset)); + h->transtable = remap_pci_mem(pci_resource_start(h->pdev, + cfg_base_addr_index)+cfg_offset+trans_offset, + sizeof(*h->transtable)); + if (!h->transtable) + return -ENOMEM; + return 0; +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { - __u64 cfg_offset; - __u32 cfg_base_addr; - __u64 cfg_base_addr_index; - __u32 trans_offset; - int i, prod_index, err; + int prod_index, err; prod_index = cciss_lookup_board_id(c->pdev, &c->board_id); if (prod_index < 0) @@ -4090,36 +4117,9 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) err = cciss_wait_for_board_ready(c); if (err) goto err_out_free_res; - - /* get the address index number */ - cfg_base_addr = readl(c->vaddr + SA5_CTCFG_OFFSET); - cfg_base_addr &= (__u32) 0x0000ffff; -#ifdef CCISS_DEBUG - printk("cfg base address = %x\n", cfg_base_addr); -#endif /* CCISS_DEBUG */ - cfg_base_addr_index = find_PCI_BAR_index(c->pdev, cfg_base_addr); -#ifdef CCISS_DEBUG - printk("cfg base address index = %llx\n", - (unsigned long long)cfg_base_addr_index); -#endif /* CCISS_DEBUG */ - if (cfg_base_addr_index == -1) { - printk(KERN_WARNING "cciss: Cannot find cfg_base_addr_index\n"); - err = -ENODEV; + err = cciss_find_cfgtables(c); + if (err) goto err_out_free_res; - } - - cfg_offset = readl(c->vaddr + SA5_CTMEM_OFFSET); -#ifdef CCISS_DEBUG - printk("cfg offset = %llx\n", (unsigned long long)cfg_offset); -#endif /* CCISS_DEBUG */ - c->cfgtable = remap_pci_mem(pci_resource_start(c->pdev, - cfg_base_addr_index) + - cfg_offset, sizeof(CfgTable_struct)); - /* Find performant mode table. */ - trans_offset = readl(&(c->cfgtable->TransMethodOffset)); - c->transtable = remap_pci_mem(pci_resource_start(c->pdev, - cfg_base_addr_index) + cfg_offset+trans_offset, - sizeof(*c->transtable)); #ifdef CCISS_DEBUG print_cfg_table(c->cfgtable); #endif /* CCISS_DEBUG */ -- cgit v1.2.3-70-g09d2 From da5503217d7421dbf04a0557d16cae6d5fc0960e Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:26 -0500 Subject: cciss: fix leak of ioremapped memory cciss: fix leak of ioremapped memory in cciss_pci_init error path. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index c297d31d0c9..b7024711060 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4114,6 +4114,10 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) if (err) goto err_out_free_res; c->vaddr = remap_pci_mem(c->paddr, 0x250); + if (!c->vaddr) { + err = -ENOMEM; + goto err_out_free_res; + } err = cciss_wait_for_board_ready(c); if (err) goto err_out_free_res; @@ -4198,6 +4202,12 @@ err_out_free_res: * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo */ + if (c->transtable) + iounmap(c->transtable); + if (c->cfgtable) + iounmap(c->cfgtable); + if (c->vaddr) + iounmap(c->vaddr); pci_release_regions(c->pdev); return err; } @@ -4745,6 +4755,8 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) pci_disable_msi(hba[i]->pdev); #endif /* CONFIG_PCI_MSI */ + iounmap(hba[i]->transtable); + iounmap(hba[i]->cfgtable); iounmap(hba[i]->vaddr); pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct), -- cgit v1.2.3-70-g09d2 From afadbf4b9591f3318508792ad98c347336a1a95d Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:31 -0500 Subject: cciss: factor out cciss_find_board_params cciss: factor out cciss_find_board_params Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 52 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 27 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b7024711060..97feb50675c 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4072,6 +4072,30 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) return 0; } +/* Interrogate the hardware for some limits: + * max commands, max SG elements without chaining, and with chaining, + * SG chain block size, etc. + */ +static void __devinit cciss_find_board_params(ctlr_info_t *h) +{ + h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); + h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ + h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); + /* + * Limit in-command s/g elements to 32 save dma'able memory. + * Howvever spec says if 0, use 31 + */ + h->max_cmd_sgentries = 31; + if (h->maxsgentries > 512) { + h->max_cmd_sgentries = 32; + h->chainsize = h->maxsgentries - h->max_cmd_sgentries + 1; + h->maxsgentries--; /* save one for chain pointer */ + } else { + h->maxsgentries = 31; /* default to traditional values */ + h->chainsize = 0; + } +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { int prod_index, err; @@ -4127,34 +4151,8 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) #ifdef CCISS_DEBUG print_cfg_table(c->cfgtable); #endif /* CCISS_DEBUG */ + cciss_find_board_params(c); - /* Some controllers support Zero Memory Raid (ZMR). - * When configured in ZMR mode the number of supported - * commands drops to 64. So instead of just setting an - * arbitrary value we make the driver a little smarter. - * We read the config table to tell us how many commands - * are supported on the controller then subtract 4 to - * leave a little room for ioctl calls. - */ - c->max_commands = readl(&(c->cfgtable->MaxPerformantModeCommands)); - c->maxsgentries = readl(&(c->cfgtable->MaxSGElements)); - - /* - * Limit native command to 32 s/g elements to save dma'able memory. - * Howvever spec says if 0, use 31 - */ - - c->max_cmd_sgentries = 31; - if (c->maxsgentries > 512) { - c->max_cmd_sgentries = 32; - c->chainsize = c->maxsgentries - c->max_cmd_sgentries + 1; - c->maxsgentries -= 1; /* account for chain pointer */ - } else { - c->maxsgentries = 31; /* Default to traditional value */ - c->chainsize = 0; /* traditional */ - } - - c->nr_cmds = c->max_commands - 4; if ((readb(&c->cfgtable->Signature[0]) != 'C') || (readb(&c->cfgtable->Signature[1]) != 'I') || (readb(&c->cfgtable->Signature[2]) != 'S') || -- cgit v1.2.3-70-g09d2 From 501b92cd6b394ba56bb978fd55606b5639b4d3fb Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:36 -0500 Subject: cciss: factor out CISS_signature_present() cciss: factor out CISS_signature_present() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 97feb50675c..9a4869572a0 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4096,6 +4096,18 @@ static void __devinit cciss_find_board_params(ctlr_info_t *h) } } +static inline bool CISS_signature_present(ctlr_info_t *h) +{ + if ((readb(&h->cfgtable->Signature[0]) != 'C') || + (readb(&h->cfgtable->Signature[1]) != 'I') || + (readb(&h->cfgtable->Signature[2]) != 'S') || + (readb(&h->cfgtable->Signature[3]) != 'S')) { + dev_warn(&h->pdev->dev, "not a valid CISS config table\n"); + return false; + } + return true; +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { int prod_index, err; @@ -4153,11 +4165,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) #endif /* CCISS_DEBUG */ cciss_find_board_params(c); - if ((readb(&c->cfgtable->Signature[0]) != 'C') || - (readb(&c->cfgtable->Signature[1]) != 'I') || - (readb(&c->cfgtable->Signature[2]) != 'S') || - (readb(&c->cfgtable->Signature[3]) != 'S')) { - printk("Does not appear to be a valid CISS config table\n"); + if (!CISS_signature_present(c)) { err = -ENODEV; goto err_out_free_res; } -- cgit v1.2.3-70-g09d2 From 322e304c4d71b79b3950ca560db4868cc3e04ee6 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:41 -0500 Subject: cciss: factor out cciss_enable_scsi_prefetch() cciss: factor out cciss_enable_scsi_prefetch() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 9a4869572a0..b4264bcda61 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4108,6 +4108,18 @@ static inline bool CISS_signature_present(ctlr_info_t *h) return true; } +/* Need to enable prefetch in the SCSI core for 6400 in x86 */ +static inline void cciss_enable_scsi_prefetch(ctlr_info_t *h) +{ +#ifdef CONFIG_X86 + u32 prefetch; + + prefetch = readl(&(h->cfgtable->SCSI_Prefetch)); + prefetch |= 0x100; + writel(prefetch, &(h->cfgtable->SCSI_Prefetch)); +#endif +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { int prod_index, err; @@ -4169,16 +4181,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) err = -ENODEV; goto err_out_free_res; } -#ifdef CONFIG_X86 - { - /* Need to enable prefetch in the SCSI core for 6400 in x86 */ - __u32 prefetch; - prefetch = readl(&(c->cfgtable->SCSI_Prefetch)); - prefetch |= 0x100; - writel(prefetch, &(c->cfgtable->SCSI_Prefetch)); - } -#endif - + cciss_enable_scsi_prefetch(c); /* Disabling DMA prefetch and refetch for the P600. * An ASIC bug may result in accesses to invalid memory addresses. * We've disabled prefetch for some time now. Testing with XEN -- cgit v1.2.3-70-g09d2 From bfd63ee571ed2a1ab7af99544e326483f84c0544 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:46 -0500 Subject: cciss: factor out cciss_p600_dma_prefetch_quirk() cciss: factor out cciss_p600_dma_prefetch_quirk() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b4264bcda61..e1c2bf1c6d6 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4120,6 +4120,24 @@ static inline void cciss_enable_scsi_prefetch(ctlr_info_t *h) #endif } +/* Disable DMA prefetch for the P600. Otherwise an ASIC bug may result + * in a prefetch beyond physical memory. + */ +static inline void cciss_p600_dma_prefetch_quirk(ctlr_info_t *h) +{ + u32 dma_prefetch; + __u32 dma_refetch; + + if (h->board_id != 0x3225103C) + return; + dma_prefetch = readl(h->vaddr + I2O_DMA1_CFG); + dma_prefetch |= 0x8000; + writel(dma_prefetch, h->vaddr + I2O_DMA1_CFG); + pci_read_config_dword(h->pdev, PCI_COMMAND_PARITY, &dma_refetch); + dma_refetch |= 0x1; + pci_write_config_dword(h->pdev, PCI_COMMAND_PARITY, dma_refetch); +} + static int __devinit cciss_pci_init(ctlr_info_t *c) { int prod_index, err; @@ -4182,24 +4200,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) goto err_out_free_res; } cciss_enable_scsi_prefetch(c); - /* Disabling DMA prefetch and refetch for the P600. - * An ASIC bug may result in accesses to invalid memory addresses. - * We've disabled prefetch for some time now. Testing with XEN - * kernels revealed a bug in the refetch if dom0 resides on a P600. - */ - if (c->board_id == 0x3225103C) { - __u32 dma_prefetch; - __u32 dma_refetch; - dma_prefetch = readl(c->vaddr + I2O_DMA1_CFG); - dma_prefetch |= 0x8000; - writel(dma_prefetch, c->vaddr + I2O_DMA1_CFG); - pci_read_config_dword(c->pdev, PCI_COMMAND_PARITY, - &dma_refetch); - dma_refetch |= 0x1; - pci_write_config_dword(c->pdev, PCI_COMMAND_PARITY, - dma_refetch); - } - + cciss_p600_dma_prefetch_quirk(c); #ifdef CCISS_DEBUG printk(KERN_WARNING "Trying to put board into Performant mode\n"); #endif /* CCISS_DEBUG */ -- cgit v1.2.3-70-g09d2 From ff5f58f06deb3f7b9a865093d7f580bbc2b9b498 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:51 -0500 Subject: cciss: cleanup some debug ifdefs cciss: cleanup some debug ifdefs Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e1c2bf1c6d6..10502a20022 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3711,9 +3711,9 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) * the io functions. * This is for debug only. */ -#ifdef CCISS_DEBUG static void print_cfg_table(CfgTable_struct *tb) { +#ifdef CCISS_DEBUG int i; char temp_name[17]; @@ -3742,8 +3742,8 @@ static void print_cfg_table(CfgTable_struct *tb) temp_name[16] = '\0'; printk(" Server Name = %s\n", temp_name); printk(" Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat))); -} #endif /* CCISS_DEBUG */ +} static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) { @@ -3833,6 +3833,7 @@ cciss_put_controller_into_performant_mode(ctlr_info_t *h) BUILD_BUG_ON(28 > MAXSGENTRIES + 4); + dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); /* Attempt to put controller into performant mode if supported */ /* Does board support performant mode? */ trans_support = readl(&(h->cfgtable->TransportSupport)); @@ -4190,9 +4191,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) err = cciss_find_cfgtables(c); if (err) goto err_out_free_res; -#ifdef CCISS_DEBUG print_cfg_table(c->cfgtable); -#endif /* CCISS_DEBUG */ cciss_find_board_params(c); if (!CISS_signature_present(c)) { @@ -4201,9 +4200,6 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) } cciss_enable_scsi_prefetch(c); cciss_p600_dma_prefetch_quirk(c); -#ifdef CCISS_DEBUG - printk(KERN_WARNING "Trying to put board into Performant mode\n"); -#endif /* CCISS_DEBUG */ cciss_put_controller_into_performant_mode(c); return 0; -- cgit v1.2.3-70-g09d2 From fe3b7527dbf1e717ccb3492bb2d84481ca7be6f9 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:45:56 -0500 Subject: cciss: make cciss_put_controller_into_performant_mode as __devinit cciss: make cciss_put_controller_into_performant_mode as __devinit Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 10502a20022..37bc091041a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3816,8 +3816,7 @@ static void calc_bucket_map(int bucket[], int num_buckets, } } -static void -cciss_put_controller_into_performant_mode(ctlr_info_t *h) +static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) { int l = 0; __u32 trans_support; -- cgit v1.2.3-70-g09d2 From 0f8a6a1e7b7162a51daee7df28f1b898da1a4165 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:01 -0500 Subject: cciss: factor out cciss_wait_for_mode_change_ack() cciss: factor out cciss_wait_for_mode_change_ack() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 37bc091041a..ee7cfde8a14 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3816,9 +3816,22 @@ static void calc_bucket_map(int bucket[], int num_buckets, } } +static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) +{ + int i; + + /* under certain very rare conditions, this can take awhile. + * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right + * as we enter this code.) */ + for (i = 0; i < MAX_CONFIG_WAIT; i++) { + if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) + break; + msleep(10); + } +} + static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) { - int l = 0; __u32 trans_support; __u32 trans_offset; /* @@ -3895,17 +3908,7 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) h->transMethod = CFGTBL_Trans_Performant; writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); - /* under certain very rare conditions, this can take awhile. - * (e.g.: hot replace a failed 144GB drive in a RAID 5 set right - * as we enter this code.) */ - for (l = 0; l < MAX_CONFIG_WAIT; l++) { - register_value = readl(h->vaddr + SA5_DOORBELL); - if (!(register_value & CFGTBL_ChangeReq)) - break; - /* delay and try again */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(10); - } + cciss_wait_for_mode_change_ack(h); register_value = readl(&(h->cfgtable->TransportActive)); if (!(register_value & CFGTBL_Trans_Performant)) { printk(KERN_WARNING "cciss: unable to get board into" -- cgit v1.2.3-70-g09d2 From b993313540de341e4c4df8f529d585e9400f43bd Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:07 -0500 Subject: cciss: factor out cciss_enter_performant_mode cciss: factor out cciss_enter_performant_mode Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 98 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 39 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index ee7cfde8a14..17e420c13b3 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3830,54 +3830,36 @@ static void __devinit cciss_wait_for_mode_change_ack(ctlr_info_t *h) } } -static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) +static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) { - __u32 trans_support; + /* This is a bit complicated. There are 8 registers on + * the controller which we write to to tell it 8 different + * sizes of commands which there may be. It's a way of + * reducing the DMA done to fetch each command. Encoded into + * each command's tag are 3 bits which communicate to the controller + * which of the eight sizes that command fits within. The size of + * each command depends on how many scatter gather entries there are. + * Each SG entry requires 16 bytes. The eight registers are programmed + * with the number of 16-byte blocks a command of that size requires. + * The smallest command possible requires 5 such 16 byte blocks. + * the largest command possible requires MAXSGENTRIES + 4 16-byte + * blocks. Note, this only extends to the SG entries contained + * within the command block, and does not extend to chained blocks + * of SG elements. bft[] contains the eight values we write to + * the registers. They are not evenly distributed, but have more + * sizes for small commands, and fewer sizes for larger commands. + */ __u32 trans_offset; + int bft[8] = { 5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4}; /* * 5 = 1 s/g entry or 4k * 6 = 2 s/g entry or 8k * 8 = 4 s/g entry or 16k * 10 = 6 s/g entry or 24k */ - int bft[8] = { 5, 6, 8, 10, 12, 20, 28, MAXSGENTRIES + 4}; unsigned long register_value; - BUILD_BUG_ON(28 > MAXSGENTRIES + 4); - dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); - /* Attempt to put controller into performant mode if supported */ - /* Does board support performant mode? */ - trans_support = readl(&(h->cfgtable->TransportSupport)); - if (!(trans_support & PERFORMANT_MODE)) - return; - - printk(KERN_WARNING "cciss%d: Placing controller into " - "performant mode\n", h->ctlr); - /* Performant mode demands commands on a 32 byte boundary - * pci_alloc_consistent aligns on page boundarys already. - * Just need to check if divisible by 32 - */ - if ((sizeof(CommandList_struct) % 32) != 0) { - printk(KERN_WARNING "%s %d %s\n", - "cciss info: command size[", - (int)sizeof(CommandList_struct), - "] not divisible by 32, no performant mode..\n"); - return; - } - - /* Performant mode ring buffer and supporting data structures */ - h->reply_pool = (__u64 *)pci_alloc_consistent( - h->pdev, h->max_commands * sizeof(__u64), - &(h->reply_pool_dhandle)); - - /* Need a block fetch table for performant mode */ - h->blockFetchTable = kmalloc(((h->maxsgentries+1) * - sizeof(__u32)), GFP_KERNEL); - - if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) - goto clean_up; - h->reply_pool_wraparound = 1; /* spec: init to 1 */ /* Controller spec: zero out this buffer. */ @@ -3906,18 +3888,56 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) writel(CFGTBL_Trans_Performant, &(h->cfgtable->HostWrite.TransportRequest)); - h->transMethod = CFGTBL_Trans_Performant; writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); cciss_wait_for_mode_change_ack(h); register_value = readl(&(h->cfgtable->TransportActive)); - if (!(register_value & CFGTBL_Trans_Performant)) { + if (!(register_value & CFGTBL_Trans_Performant)) printk(KERN_WARNING "cciss: unable to get board into" " performant mode\n"); +} + +static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) +{ + __u32 trans_support; + + dev_dbg(&h->pdev->dev, "Trying to put board into Performant mode\n"); + /* Attempt to put controller into performant mode if supported */ + /* Does board support performant mode? */ + trans_support = readl(&(h->cfgtable->TransportSupport)); + if (!(trans_support & PERFORMANT_MODE)) + return; + + printk(KERN_WARNING "cciss%d: Placing controller into " + "performant mode\n", h->ctlr); + /* Performant mode demands commands on a 32 byte boundary + * pci_alloc_consistent aligns on page boundarys already. + * Just need to check if divisible by 32 + */ + if ((sizeof(CommandList_struct) % 32) != 0) { + printk(KERN_WARNING "%s %d %s\n", + "cciss info: command size[", + (int)sizeof(CommandList_struct), + "] not divisible by 32, no performant mode..\n"); return; } + /* Performant mode ring buffer and supporting data structures */ + h->reply_pool = (__u64 *)pci_alloc_consistent( + h->pdev, h->max_commands * sizeof(__u64), + &(h->reply_pool_dhandle)); + + /* Need a block fetch table for performant mode */ + h->blockFetchTable = kmalloc(((h->maxsgentries+1) * + sizeof(__u32)), GFP_KERNEL); + + if ((h->reply_pool == NULL) || (h->blockFetchTable == NULL)) + goto clean_up; + + cciss_enter_performant_mode(h); + /* Change the access methods to the performant access methods */ h->access = SA5_performant_access; + h->transMethod = CFGTBL_Trans_Performant; return; clean_up: -- cgit v1.2.3-70-g09d2 From 8e93bf6d6c9c6d864c17b7743f2cc5f2e052fe46 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:12 -0500 Subject: cciss: factor out cciss_find_cfg_addrs. Rationale for this is that I will also need to use this code in fixing kdump host reset code prior to having the hba structure. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 17e420c13b3..3cd8397f82b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4064,29 +4064,40 @@ static int __devinit cciss_wait_for_board_ready(ctlr_info_t *h) return -ENODEV; } +static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, + void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, + u64 *cfg_offset) +{ + *cfg_base_addr = readl(vaddr + SA5_CTCFG_OFFSET); + *cfg_offset = readl(vaddr + SA5_CTMEM_OFFSET); + *cfg_base_addr &= (u32) 0x0000ffff; + *cfg_base_addr_index = find_PCI_BAR_index(pdev, *cfg_base_addr); + if (*cfg_base_addr_index == -1) { + dev_warn(&pdev->dev, "cannot find cfg_base_addr_index, " + "*cfg_base_addr = 0x%08x\n", *cfg_base_addr); + return -ENODEV; + } + return 0; +} + static int __devinit cciss_find_cfgtables(ctlr_info_t *h) { u64 cfg_offset; u32 cfg_base_addr; u64 cfg_base_addr_index; u32 trans_offset; + int rc; - /* get the address index number */ - cfg_base_addr = readl(h->vaddr + SA5_CTCFG_OFFSET); - cfg_base_addr &= (u32) 0x0000ffff; - cfg_base_addr_index = find_PCI_BAR_index(h->pdev, cfg_base_addr); - if (cfg_base_addr_index == -1) { - dev_warn(&h->pdev->dev, "cannot find cfg_base_addr_index\n"); - return -ENODEV; - } - cfg_offset = readl(h->vaddr + SA5_CTMEM_OFFSET); + rc = cciss_find_cfg_addrs(h->pdev, h->vaddr, &cfg_base_addr, + &cfg_base_addr_index, &cfg_offset); + if (rc) + return rc; h->cfgtable = remap_pci_mem(pci_resource_start(h->pdev, - cfg_base_addr_index) + cfg_offset, - sizeof(h->cfgtable)); + cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable)); if (!h->cfgtable) return -ENOMEM; /* Find performant mode table. */ - trans_offset = readl(&(h->cfgtable->TransMethodOffset)); + trans_offset = readl(&h->cfgtable->TransMethodOffset); h->transtable = remap_pci_mem(pci_resource_start(h->pdev, cfg_base_addr_index)+cfg_offset+trans_offset, sizeof(*h->transtable)); -- cgit v1.2.3-70-g09d2 From 83123cb11b5a5205233c59357da2c8d9a8dc9d24 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:17 -0500 Subject: cciss: factor out cciss_reset_devices() cciss: factor out cciss_reset_devices() Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 51 +++++++++++++++++++++++++++++++-------------------- drivers/block/cciss.h | 3 +++ 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 3cd8397f82b..f49dcd734d1 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4486,6 +4486,34 @@ static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) return 0; } +static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) +{ + int i; + + if (!reset_devices) + return 0; + + /* Reset the controller with a PCI power-cycle */ + if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) + return -ENODEV; + + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + msleep(CCISS_POST_RESET_PAUSE_MSECS); + + /* Now try to get the controller to respond to a no-op */ + for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { + if (cciss_noop(pdev) == 0) + break; + else + dev_warn(&pdev->dev, "no-op failed%s\n", + (i < CCISS_POST_RESET_NOOP_RETRIES - 1 ? + "; re-trying" : "")); + msleep(CCISS_POST_RESET_NOOP_INTERVAL_MSECS); + } + return 0; +} + /* * This is it. Find all the controllers and register them. I really hate * stealing all these major device numbers. @@ -4501,26 +4529,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int dac, return_code; InquiryData_struct *inq_buff; - if (reset_devices) { - /* Reset the controller with a PCI power-cycle */ - if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) - return -ENODEV; - - /* Now try to get the controller to respond to a no-op. Some - devices (notably the HP Smart Array 5i Controller) need - up to 30 seconds to respond. */ - for (i=0; i<30; i++) { - if (cciss_noop(pdev) == 0) - break; - - schedule_timeout_uninterruptible(HZ); - } - if (i == 30) { - printk(KERN_ERR "cciss: controller seems dead\n"); - return -EBUSY; - } - } - + rc = cciss_init_reset_devices(pdev); + if (rc) + return rc; i = alloc_cciss_hba(); if (i < 0) return -1; diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index c2ef9dd56c4..4290b7f0f63 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -204,6 +204,9 @@ struct ctlr_info #define CCISS_BOARD_READY_ITERATIONS \ ((CCISS_BOARD_READY_WAIT_SECS * 1000) / \ CCISS_BOARD_READY_POLL_INTERVAL_MSECS) +#define CCISS_POST_RESET_PAUSE_MSECS (3000) +#define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000) +#define CCISS_POST_RESET_NOOP_RETRIES (12) /* Send the command to the hardware -- cgit v1.2.3-70-g09d2 From a6528d017234b483283274fbdd360f3541befe19 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:22 -0500 Subject: cciss: fix hard reset code. cciss: Fix hard reset code. Smart Array controllers newer than the P600 do not honor the PCI power state method of resetting the controllers. Instead, in these cases we can get them to reset via the "doorbell" register. This escaped notice until we began using "performant" mode because the fact that the controllers did not reset did not normally impede subsequent operation, and so things generally appeared to "work". Once the performant mode code was added, if the controller does not reset, it remains in performant mode. The code immediately after the reset presumes the controller is in "simple" mode (which previously, it had remained in simple mode the whole time). If the controller remains in performant mode any code which presumes it is in simple mode will not work. So the reset needs to be fixed. Unfortunately there are some controllers which cannot be reset by either method. (eg. p800). We detect these cases by noticing that the controller seems to remain in performant mode even after a reset has been attempted. In those cases we ignore the controller, as any commands outstanding on it will result in stale completions. To sum up, we try to do a better job of resetting the controller if "reset_devices" is set, and if it doesn't work, we ignore that controller. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 200 ++++++++++++++++++++++++++++++++++------------ drivers/block/cciss_cmd.h | 4 + 2 files changed, 152 insertions(+), 52 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f49dcd734d1..b3060eced55 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -216,6 +216,12 @@ static void cciss_device_release(struct device *dev); static void cciss_free_gendisk(ctlr_info_t *h, int drv_index); static void cciss_free_drive_info(ctlr_info_t *h, int drv_index); static inline u32 next_command(ctlr_info_t *h); +static int __devinit cciss_find_cfg_addrs(struct pci_dev *pdev, + void __iomem *vaddr, u32 *cfg_base_addr, u64 *cfg_base_addr_index, + u64 *cfg_offset); +static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev, + unsigned long *memory_bar); + /* performant mode helper functions */ static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, @@ -4413,68 +4419,130 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) return 0; } -/* This does a hard reset of the controller using PCI power management - * states. */ -static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) +static int cciss_controller_hard_reset(struct pci_dev *pdev, + void * __iomem vaddr, bool use_doorbell) { - u16 pmcsr, saved_config_space[32]; - int i, pos; + u16 pmcsr; + int pos; - printk(KERN_INFO "cciss: using PCI PM to reset controller\n"); + if (use_doorbell) { + /* For everything after the P600, the PCI power state method + * of resetting the controller doesn't work, so we have this + * other way using the doorbell register. + */ + dev_info(&pdev->dev, "using doorbell to reset controller\n"); + writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL); + msleep(1000); + } else { /* Try to do it the PCI power state way */ + + /* Quoting from the Open CISS Specification: "The Power + * Management Control/Status Register (CSR) controls the power + * state of the device. The normal operating state is D0, + * CSR=00h. The software off state is D3, CSR=03h. To reset + * the controller, place the interface device in D3 then to D0, + * this causes a secondary PCI reset which will reset the + * controller." */ + + pos = pci_find_capability(pdev, PCI_CAP_ID_PM); + if (pos == 0) { + dev_err(&pdev->dev, + "cciss_controller_hard_reset: " + "PCI PM not supported\n"); + return -ENODEV; + } + dev_info(&pdev->dev, "using PCI PM to reset controller\n"); + /* enter the D3hot power management state */ + pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D3hot; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - /* This is very nearly the same thing as + msleep(500); - pci_save_state(pci_dev); - pci_set_power_state(pci_dev, PCI_D3hot); - pci_set_power_state(pci_dev, PCI_D0); - pci_restore_state(pci_dev); + /* enter the D0 power management state */ + pmcsr &= ~PCI_PM_CTRL_STATE_MASK; + pmcsr |= PCI_D0; + pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); - but we can't use these nice canned kernel routines on - kexec, because they also check the MSI/MSI-X state in PCI - configuration space and do the wrong thing when it is - set/cleared. Also, the pci_save/restore_state functions - violate the ordering requirements for restoring the - configuration space from the CCISS document (see the - comment below). So we roll our own .... */ + msleep(500); + } + return 0; +} + +/* This does a hard reset of the controller using PCI power management + * states or using the doorbell register. */ +static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) +{ + u16 saved_config_space[32]; + u64 cfg_offset; + u32 cfg_base_addr; + u64 cfg_base_addr_index; + void __iomem *vaddr; + unsigned long paddr; + u32 misc_fw_support, active_transport; + int rc, i; + CfgTable_struct __iomem *cfgtable; + bool use_doorbell; + + /* For controllers as old a the p600, this is very nearly + * the same thing as + * + * pci_save_state(pci_dev); + * pci_set_power_state(pci_dev, PCI_D3hot); + * pci_set_power_state(pci_dev, PCI_D0); + * pci_restore_state(pci_dev); + * + * but we can't use these nice canned kernel routines on + * kexec, because they also check the MSI/MSI-X state in PCI + * configuration space and do the wrong thing when it is + * set/cleared. Also, the pci_save/restore_state functions + * violate the ordering requirements for restoring the + * configuration space from the CCISS document (see the + * comment below). So we roll our own .... + * + * For controllers newer than the P600, the pci power state + * method of resetting doesn't work so we have another way + * using the doorbell register. + */ for (i = 0; i < 32; i++) pci_read_config_word(pdev, 2*i, &saved_config_space[i]); - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos == 0) { - printk(KERN_ERR "cciss_reset_controller: PCI PM not supported\n"); - return -ENODEV; - } - - /* Quoting from the Open CISS Specification: "The Power - * Management Control/Status Register (CSR) controls the power - * state of the device. The normal operating state is D0, - * CSR=00h. The software off state is D3, CSR=03h. To reset - * the controller, place the interface device in D3 then to - * D0, this causes a secondary PCI reset which will reset the - * controller." */ - - /* enter the D3hot power management state */ - pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D3hot; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + /* find the first memory BAR, so we can find the cfg table */ + rc = cciss_pci_find_memory_BAR(pdev, &paddr); + if (rc) + return rc; + vaddr = remap_pci_mem(paddr, 0x250); + if (!vaddr) + return -ENOMEM; - schedule_timeout_uninterruptible(HZ >> 1); + /* find cfgtable in order to check if reset via doorbell is supported */ + rc = cciss_find_cfg_addrs(pdev, vaddr, &cfg_base_addr, + &cfg_base_addr_index, &cfg_offset); + if (rc) + goto unmap_vaddr; + cfgtable = remap_pci_mem(pci_resource_start(pdev, + cfg_base_addr_index) + cfg_offset, sizeof(*cfgtable)); + if (!cfgtable) { + rc = -ENOMEM; + goto unmap_vaddr; + } - /* enter the D0 power management state */ - pmcsr &= ~PCI_PM_CTRL_STATE_MASK; - pmcsr |= PCI_D0; - pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr); + /* If reset via doorbell register is supported, use that. */ + misc_fw_support = readl(&cfgtable->misc_fw_support); + use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; - schedule_timeout_uninterruptible(HZ >> 1); + rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); + if (rc) + goto unmap_cfgtable; /* Restore the PCI configuration space. The Open CISS * Specification says, "Restore the PCI Configuration * Registers, offsets 00h through 60h. It is important to * restore the command register, 16-bits at offset 04h, * last. Do not restore the configuration status register, - * 16-bits at offset 06h." Note that the offset is 2*i. */ + * 16-bits at offset 06h." Note that the offset is 2*i. + */ for (i = 0; i < 32; i++) { if (i == 2 || i == 3) continue; @@ -4483,23 +4551,51 @@ static __devinit int cciss_hard_reset_controller(struct pci_dev *pdev) wmb(); pci_write_config_word(pdev, 4, saved_config_space[2]); - return 0; + /* Some devices (notably the HP Smart Array 5i Controller) + need a little pause here */ + msleep(CCISS_POST_RESET_PAUSE_MSECS); + + /* Controller should be in simple mode at this point. If it's not, + * It means we're on one of those controllers which doesn't support + * the doorbell reset method and on which the PCI power management reset + * method doesn't work (P800, for example.) + * In those cases, don't try to proceed, as it generally doesn't work. + */ + active_transport = readl(&cfgtable->TransportActive); + if (active_transport & PERFORMANT_MODE) { + dev_warn(&pdev->dev, "Unable to successfully reset controller," + " Ignoring controller.\n"); + rc = -ENODEV; + } + +unmap_cfgtable: + iounmap(cfgtable); + +unmap_vaddr: + iounmap(vaddr); + return rc; } static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) { - int i; + int rc, i; if (!reset_devices) return 0; - /* Reset the controller with a PCI power-cycle */ - if (cciss_hard_reset_controller(pdev) || cciss_reset_msi(pdev)) - return -ENODEV; + /* Reset the controller with a PCI power-cycle or via doorbell */ + rc = cciss_kdump_hard_reset_controller(pdev); - /* Some devices (notably the HP Smart Array 5i Controller) - need a little pause here */ - msleep(CCISS_POST_RESET_PAUSE_MSECS); + /* -ENOTSUPP here means we cannot reset the controller + * but it's already (and still) up and running in + * "performant mode". + */ + if (rc == -ENOTSUPP) + return 0; /* just try to do the kdump anyhow. */ + if (rc) + return -ENODEV; + if (cciss_reset_msi(pdev)) + return -ENODEV; /* Now try to get the controller to respond to a no-op */ for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) { diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h index 936b9666da6..eb060f1b00b 100644 --- a/drivers/block/cciss_cmd.h +++ b/drivers/block/cciss_cmd.h @@ -52,6 +52,7 @@ /* Configuration Table */ #define CFGTBL_ChangeReq 0x00000001l #define CFGTBL_AccCmds 0x00000001l +#define DOORBELL_CTLR_RESET 0x00000004l #define CFGTBL_Trans_Simple 0x00000002l #define CFGTBL_Trans_Performant 0x00000004l @@ -230,6 +231,9 @@ typedef struct _CfgTable_struct { DWORD MaxPhysicalDrives; DWORD MaxPhysicalDrivesPerLogicalUnit; DWORD MaxPerformantModeCommands; + u8 reserved[0x78 - 0x58]; + u32 misc_fw_support; /* offset 0x78 */ +#define MISC_FW_DOORBELL_RESET (0x02) } CfgTable_struct; struct TransTable_struct { -- cgit v1.2.3-70-g09d2 From adfbc1ff342ece2e482254bcc5381fadfffbbb89 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:28 -0500 Subject: cciss: sanitize max commands cciss: sanitize max commands Some controllers might try to tell us they support 0 commands in performant mode. This is a lie told by buggy firmware. We have to be wary of this lest we try to allocate a negative number of command blocks, which will be treated as unsigned, and get an out of memory condition. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index b3060eced55..6d4c4f227d5 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4112,13 +4112,25 @@ static int __devinit cciss_find_cfgtables(ctlr_info_t *h) return 0; } +static void __devinit cciss_get_max_perf_mode_cmds(struct ctlr_info *h) +{ + h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); + if (h->max_commands < 16) { + dev_warn(&h->pdev->dev, "Controller reports " + "max supported commands of %d, an obvious lie. " + "Using 16. Ensure that firmware is up to date.\n", + h->max_commands); + h->max_commands = 16; + } +} + /* Interrogate the hardware for some limits: * max commands, max SG elements without chaining, and with chaining, * SG chain block size, etc. */ static void __devinit cciss_find_board_params(ctlr_info_t *h) { - h->max_commands = readl(&(h->cfgtable->MaxPerformantModeCommands)); + cciss_get_max_perf_mode_cmds(h); h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */ h->maxsgentries = readl(&(h->cfgtable->MaxSGElements)); /* -- cgit v1.2.3-70-g09d2 From 058a0f9f31283d5eb9d8686d3b4f69e55d1589f1 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:33 -0500 Subject: cciss: forbid hard reset of 640x boards cciss: forbid hard reset of 640x boards The 6402/6404 are two PCI devices -- two Smart Array controllers -- that fit into one slot. It is possible to reset them independently, however, they share a battery backed cache module. One of the pair controls the cache and the 2nd one access the cache through the first one. If you reset the one controlling the cache, the other one will not be a happy camper. So we just forbid resetting this conjoined mess. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6d4c4f227d5..2abe6df9445 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -4495,6 +4495,7 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) int rc, i; CfgTable_struct __iomem *cfgtable; bool use_doorbell; + u32 board_id; /* For controllers as old a the p600, this is very nearly * the same thing as @@ -4517,6 +4518,19 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev) * using the doorbell register. */ + /* Exclude 640x boards. These are two pci devices in one slot + * which share a battery backed cache module. One controls the + * cache, the other accesses the cache through the one that controls + * it. If we reset the one controlling the cache, the other will + * likely not be happy. Just forbid resetting this conjoined mess. + */ + cciss_lookup_board_id(pdev, &board_id); + if (board_id == 0x409C0E11 || board_id == 0x409D0E11) { + dev_warn(&pdev->dev, "Cannot reset Smart Array 640x " + "due to shared cache module."); + return -ENODEV; + } + for (i = 0; i < 32; i++) pci_read_config_word(pdev, 2*i, &saved_config_space[i]); @@ -4600,7 +4614,8 @@ static __devinit int cciss_init_reset_devices(struct pci_dev *pdev) /* -ENOTSUPP here means we cannot reset the controller * but it's already (and still) up and running in - * "performant mode". + * "performant mode". Or, it might be 640x, which can't reset + * due to concerns about shared bbwc between 6402/6404 pair. */ if (rc == -ENOTSUPP) return 0; /* just try to do the kdump anyhow. */ -- cgit v1.2.3-70-g09d2 From f70dba83669bf718c2f1731f0f58b8149e883593 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:38 -0500 Subject: cciss: use consistent variable names cciss: use consistent variable names "h", for the hba structure and "c" for the command structures. and get rid of trivial CCISS_LOCK macro. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 611 ++++++++++++++++++++++----------------------- drivers/block/cciss.h | 2 - drivers/block/cciss_scsi.c | 591 +++++++++++++++++++++---------------------- 3 files changed, 592 insertions(+), 612 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 2abe6df9445..70ad24f3604 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -191,17 +191,17 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl); static int deregister_disk(ctlr_info_t *h, int drv_index, int clear_all, int via_ioctl); -static void cciss_read_capacity(int ctlr, int logvol, +static void cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size, unsigned int *block_size); -static void cciss_read_capacity_16(int ctlr, int logvol, +static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, sector_t *total_size, unsigned int *block_size); -static void cciss_geometry_inquiry(int ctlr, int logvol, +static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, sector_t total_size, unsigned int block_size, InquiryData_struct *inq_buff, drive_info_struct *drv); static void __devinit cciss_interrupt_mode(ctlr_info_t *); static void start_io(ctlr_info_t *h); -static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, +static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, __u8 page_code, unsigned char scsi3addr[], int cmd_type); static int sendcmd_withirq_core(ctlr_info_t *h, CommandList_struct *c, @@ -229,9 +229,9 @@ static void calc_bucket_map(int *bucket, int num_buckets, int nsgs, static void cciss_put_controller_into_performant_mode(ctlr_info_t *h); #ifdef CONFIG_PROC_FS -static void cciss_procinit(int i); +static void cciss_procinit(ctlr_info_t *h); #else -static void cciss_procinit(int i) +static void cciss_procinit(ctlr_info_t *h) { } #endif /* CONFIG_PROC_FS */ @@ -416,26 +416,25 @@ static void cciss_seq_show_header(struct seq_file *seq) h->maxQsinceinit, h->max_outstanding, h->maxSG); #ifdef CONFIG_CISS_SCSI_TAPE - cciss_seq_tape_report(seq, h->ctlr); + cciss_seq_tape_report(seq, h); #endif /* CONFIG_CISS_SCSI_TAPE */ } static void *cciss_seq_start(struct seq_file *seq, loff_t *pos) { ctlr_info_t *h = seq->private; - unsigned ctlr = h->ctlr; unsigned long flags; /* prevent displaying bogus info during configuration * or deconfiguration of a logical volume */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return ERR_PTR(-EBUSY); } h->busy_configuring = 1; - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (*pos == 0) cciss_seq_show_header(seq); @@ -543,7 +542,7 @@ cciss_proc_write(struct file *file, const char __user *buf, struct seq_file *seq = file->private_data; ctlr_info_t *h = seq->private; - err = cciss_engage_scsi(h->ctlr); + err = cciss_engage_scsi(h); if (err == 0) err = length; } else @@ -566,7 +565,7 @@ static const struct file_operations cciss_proc_fops = { .write = cciss_proc_write, }; -static void __devinit cciss_procinit(int i) +static void __devinit cciss_procinit(ctlr_info_t *h) { struct proc_dir_entry *pde; @@ -574,9 +573,9 @@ static void __devinit cciss_procinit(int i) proc_cciss = proc_mkdir("driver/cciss", NULL); if (!proc_cciss) return; - pde = proc_create_data(hba[i]->devname, S_IWUSR | S_IRUSR | S_IRGRP | + pde = proc_create_data(h->devname, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, proc_cciss, - &cciss_proc_fops, hba[i]); + &cciss_proc_fops, h); } #endif /* CONFIG_PROC_FS */ @@ -609,12 +608,12 @@ static ssize_t dev_show_unique_id(struct device *dev, unsigned long flags; int ret = 0; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) ret = -EBUSY; else memcpy(sn, drv->serial_no, sizeof(sn)); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (ret) return ret; @@ -639,12 +638,12 @@ static ssize_t dev_show_vendor(struct device *dev, unsigned long flags; int ret = 0; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) ret = -EBUSY; else memcpy(vendor, drv->vendor, VENDOR_LEN + 1); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (ret) return ret; @@ -663,12 +662,12 @@ static ssize_t dev_show_model(struct device *dev, unsigned long flags; int ret = 0; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) ret = -EBUSY; else memcpy(model, drv->model, MODEL_LEN + 1); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (ret) return ret; @@ -687,12 +686,12 @@ static ssize_t dev_show_rev(struct device *dev, unsigned long flags; int ret = 0; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) ret = -EBUSY; else memcpy(rev, drv->rev, REV_LEN + 1); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (ret) return ret; @@ -709,17 +708,17 @@ static ssize_t cciss_show_lunid(struct device *dev, unsigned long flags; unsigned char lunid[8]; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return -EBUSY; } if (!drv->heads) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return -ENOTTY; } memcpy(lunid, drv->LunID, sizeof(lunid)); - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return snprintf(buf, 20, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", lunid[0], lunid[1], lunid[2], lunid[3], lunid[4], lunid[5], lunid[6], lunid[7]); @@ -734,13 +733,13 @@ static ssize_t cciss_show_raid_level(struct device *dev, int raid; unsigned long flags; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return -EBUSY; } raid = drv->raid_level; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (raid < 0 || raid > RAID_UNKNOWN) raid = RAID_UNKNOWN; @@ -757,13 +756,13 @@ static ssize_t cciss_show_usage_count(struct device *dev, unsigned long flags; int count; - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return -EBUSY; } count = drv->usage_count; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return snprintf(buf, 20, "%d\n", count); } static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); @@ -1012,7 +1011,7 @@ static inline drive_info_struct *get_drv(struct gendisk *disk) */ static int cciss_open(struct block_device *bdev, fmode_t mode) { - ctlr_info_t *host = get_host(bdev->bd_disk); + ctlr_info_t *h = get_host(bdev->bd_disk); drive_info_struct *drv = get_drv(bdev->bd_disk); #ifdef CCISS_DEBUG @@ -1044,7 +1043,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) return -EPERM; } drv->usage_count++; - host->usage_count++; + h->usage_count++; return 0; } @@ -1064,11 +1063,11 @@ static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode) */ static int cciss_release(struct gendisk *disk, fmode_t mode) { - ctlr_info_t *host; + ctlr_info_t *h; drive_info_struct *drv; lock_kernel(); - host = get_host(disk); + h = get_host(disk); drv = get_drv(disk); #ifdef CCISS_DEBUG @@ -1076,7 +1075,7 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) #endif /* CCISS_DEBUG */ drv->usage_count--; - host->usage_count--; + h->usage_count--; unlock_kernel(); return 0; } @@ -1223,11 +1222,11 @@ static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo) return 0; } -static void check_ioctl_unit_attention(ctlr_info_t *host, CommandList_struct *c) +static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c) { if (c->err_info->CommandStatus == CMD_TARGET_STATUS && c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) - (void)check_for_unit_attention(host, c); + (void)check_for_unit_attention(h, c); } /* * ioctl @@ -1236,9 +1235,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { struct gendisk *disk = bdev->bd_disk; - ctlr_info_t *host = get_host(disk); + ctlr_info_t *h = get_host(disk); drive_info_struct *drv = get_drv(disk); - int ctlr = host->ctlr; void __user *argp = (void __user *)arg; #ifdef CCISS_DEBUG @@ -1252,10 +1250,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (!arg) return -EINVAL; - pciinfo.domain = pci_domain_nr(host->pdev->bus); - pciinfo.bus = host->pdev->bus->number; - pciinfo.dev_fn = host->pdev->devfn; - pciinfo.board_id = host->board_id; + pciinfo.domain = pci_domain_nr(h->pdev->bus); + pciinfo.bus = h->pdev->bus->number; + pciinfo.dev_fn = h->pdev->devfn; + pciinfo.board_id = h->board_id; if (copy_to_user (argp, &pciinfo, sizeof(cciss_pci_info_struct))) return -EFAULT; @@ -1267,9 +1265,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (!arg) return -EINVAL; intinfo.delay = - readl(&host->cfgtable->HostWrite.CoalIntDelay); + readl(&h->cfgtable->HostWrite.CoalIntDelay); intinfo.count = - readl(&host->cfgtable->HostWrite.CoalIntCount); + readl(&h->cfgtable->HostWrite.CoalIntCount); if (copy_to_user (argp, &intinfo, sizeof(cciss_coalint_struct))) return -EFAULT; @@ -1293,22 +1291,22 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, // printk("cciss_ioctl: delay and count cannot be 0\n"); return -EINVAL; } - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + spin_lock_irqsave(&h->lock, flags); /* Update the field, and then ring the doorbell */ writel(intinfo.delay, - &(host->cfgtable->HostWrite.CoalIntDelay)); + &(h->cfgtable->HostWrite.CoalIntDelay)); writel(intinfo.count, - &(host->cfgtable->HostWrite.CoalIntCount)); - writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); + &(h->cfgtable->HostWrite.CoalIntCount)); + writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { - if (!(readl(host->vaddr + SA5_DOORBELL) + if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; /* delay and try again */ udelay(1000); } - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (i >= MAX_IOCTL_CONFIG_WAIT) return -EAGAIN; return 0; @@ -1322,7 +1320,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, return -EINVAL; for (i = 0; i < 16; i++) NodeName[i] = - readb(&host->cfgtable->ServerName[i]); + readb(&h->cfgtable->ServerName[i]); if (copy_to_user(argp, NodeName, sizeof(NodeName_type))) return -EFAULT; return 0; @@ -1342,23 +1340,23 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, (NodeName, argp, sizeof(NodeName_type))) return -EFAULT; - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + spin_lock_irqsave(&h->lock, flags); /* Update the field, and then ring the doorbell */ for (i = 0; i < 16; i++) writeb(NodeName[i], - &host->cfgtable->ServerName[i]); + &h->cfgtable->ServerName[i]); - writel(CFGTBL_ChangeReq, host->vaddr + SA5_DOORBELL); + writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL); for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) { - if (!(readl(host->vaddr + SA5_DOORBELL) + if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq)) break; /* delay and try again */ udelay(1000); } - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); if (i >= MAX_IOCTL_CONFIG_WAIT) return -EAGAIN; return 0; @@ -1370,7 +1368,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (!arg) return -EINVAL; - heartbeat = readl(&host->cfgtable->HeartBeat); + heartbeat = readl(&h->cfgtable->HeartBeat); if (copy_to_user (argp, &heartbeat, sizeof(Heartbeat_type))) return -EFAULT; @@ -1382,7 +1380,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (!arg) return -EINVAL; - BusTypes = readl(&host->cfgtable->BusTypes); + BusTypes = readl(&h->cfgtable->BusTypes); if (copy_to_user (argp, &BusTypes, sizeof(BusTypes_type))) return -EFAULT; @@ -1394,7 +1392,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (!arg) return -EINVAL; - memcpy(firmware, host->firm_ver, 4); + memcpy(firmware, h->firm_ver, 4); if (copy_to_user (argp, firmware, sizeof(FirmwareVer_type))) @@ -1417,7 +1415,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, case CCISS_DEREGDISK: case CCISS_REGNEWD: case CCISS_REVALIDVOLS: - return rebuild_lun_table(host, 0, 1); + return rebuild_lun_table(h, 0, 1); case CCISS_GETLUNINFO:{ LogvolInfo_struct luninfo; @@ -1472,7 +1470,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } else { memset(buff, 0, iocommand.buf_size); } - if ((c = cmd_alloc(host, 0)) == NULL) { + c = cmd_alloc(h, 0); + if (!c) { kfree(buff); return -ENOMEM; } @@ -1498,7 +1497,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, /* Fill in the scatter gather information */ if (iocommand.buf_size > 0) { - temp64.val = pci_map_single(host->pdev, buff, + temp64.val = pci_map_single(h->pdev, buff, iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); c->SG[0].Addr.lower = temp64.val32.lower; @@ -1508,24 +1507,24 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } c->waiting = &wait; - enqueue_cmd_and_start_io(host, c); + enqueue_cmd_and_start_io(h, c); wait_for_completion(&wait); /* unlock the buffers from DMA */ temp64.val32.lower = c->SG[0].Addr.lower; temp64.val32.upper = c->SG[0].Addr.upper; - pci_unmap_single(host->pdev, (dma_addr_t) temp64.val, + pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size, PCI_DMA_BIDIRECTIONAL); - check_ioctl_unit_attention(host, c); + check_ioctl_unit_attention(h, c); /* Copy the error information out */ iocommand.error_info = *(c->err_info); if (copy_to_user (argp, &iocommand, sizeof(IOCTL_Command_struct))) { kfree(buff); - cmd_free(host, c, 0); + cmd_free(h, c, 0); return -EFAULT; } @@ -1534,12 +1533,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (copy_to_user (iocommand.buf, buff, iocommand.buf_size)) { kfree(buff); - cmd_free(host, c, 0); + cmd_free(h, c, 0); return -EFAULT; } } kfree(buff); - cmd_free(host, c, 0); + cmd_free(h, c, 0); return 0; } case CCISS_BIG_PASSTHRU:{ @@ -1621,7 +1620,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, data_ptr += sz; sg_used++; } - if ((c = cmd_alloc(host, 0)) == NULL) { + c = cmd_alloc(h, 0); + if (!c) { status = -ENOMEM; goto cleanup1; } @@ -1642,7 +1642,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (ioc->buf_size > 0) { for (i = 0; i < sg_used; i++) { temp64.val = - pci_map_single(host->pdev, buff[i], + pci_map_single(h->pdev, buff[i], buff_size[i], PCI_DMA_BIDIRECTIONAL); c->SG[i].Addr.lower = @@ -1654,21 +1654,21 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } } c->waiting = &wait; - enqueue_cmd_and_start_io(host, c); + enqueue_cmd_and_start_io(h, c); wait_for_completion(&wait); /* unlock the buffers from DMA */ for (i = 0; i < sg_used; i++) { temp64.val32.lower = c->SG[i].Addr.lower; temp64.val32.upper = c->SG[i].Addr.upper; - pci_unmap_single(host->pdev, + pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, buff_size[i], PCI_DMA_BIDIRECTIONAL); } - check_ioctl_unit_attention(host, c); + check_ioctl_unit_attention(h, c); /* Copy the error information out */ ioc->error_info = *(c->err_info); if (copy_to_user(argp, ioc, sizeof(*ioc))) { - cmd_free(host, c, 0); + cmd_free(h, c, 0); status = -EFAULT; goto cleanup1; } @@ -1678,14 +1678,14 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, for (i = 0; i < sg_used; i++) { if (copy_to_user (ptr, buff[i], buff_size[i])) { - cmd_free(host, c, 0); + cmd_free(h, c, 0); status = -EFAULT; goto cleanup1; } ptr += buff_size[i]; } } - cmd_free(host, c, 0); + cmd_free(h, c, 0); status = 0; cleanup1: if (buff) { @@ -1773,26 +1773,26 @@ static void cciss_check_queues(ctlr_info_t *h) static void cciss_softirq_done(struct request *rq) { - CommandList_struct *cmd = rq->completion_data; - ctlr_info_t *h = hba[cmd->ctlr]; - SGDescriptor_struct *curr_sg = cmd->SG; + CommandList_struct *c = rq->completion_data; + ctlr_info_t *h = hba[c->ctlr]; + SGDescriptor_struct *curr_sg = c->SG; u64bit temp64; unsigned long flags; int i, ddir; int sg_index = 0; - if (cmd->Request.Type.Direction == XFER_READ) + if (c->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++) { + for (i = 0; i < c->Header.SGList; i++) { if (curr_sg[sg_index].Ext == CCISS_SG_CHAIN) { - cciss_unmap_sg_chain_block(h, cmd); + cciss_unmap_sg_chain_block(h, c); /* Point to the next block */ - curr_sg = h->cmd_sg_list[cmd->cmdindex]; + curr_sg = h->cmd_sg_list[c->cmdindex]; sg_index = 0; } temp64.val32.lower = curr_sg[sg_index].Addr.lower; @@ -1808,12 +1808,12 @@ static void cciss_softirq_done(struct request *rq) /* set the residual count for pc requests */ if (rq->cmd_type == REQ_TYPE_BLOCK_PC) - rq->resid_len = cmd->err_info->ResidualCnt; + rq->resid_len = c->err_info->ResidualCnt; blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); spin_lock_irqsave(&h->lock, flags); - cmd_free(h, cmd, 1); + cmd_free(h, c, 1); cciss_check_queues(h); spin_unlock_irqrestore(&h->lock, flags); } @@ -1829,7 +1829,7 @@ static inline void log_unit_to_scsi3addr(ctlr_info_t *h, * via the inquiry page 0. Model, vendor, and rev are set to empty strings if * they cannot be read. */ -static void cciss_get_device_descr(int ctlr, int logvol, +static void cciss_get_device_descr(ctlr_info_t *h, int logvol, char *vendor, char *model, char *rev) { int rc; @@ -1844,8 +1844,8 @@ static void cciss_get_device_descr(int ctlr, int logvol, if (!inq_buf) return; - log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); - rc = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buf, sizeof(*inq_buf), 0, + log_unit_to_scsi3addr(h, scsi3addr, logvol); + rc = sendcmd_withirq(h, CISS_INQUIRY, inq_buf, sizeof(*inq_buf), 0, scsi3addr, TYPE_CMD); if (rc == IO_OK) { memcpy(vendor, &inq_buf->data_byte[8], VENDOR_LEN); @@ -1865,7 +1865,7 @@ static void cciss_get_device_descr(int ctlr, int logvol, * number cannot be had, for whatever reason, 16 bytes of 0xff * are returned instead. */ -static void cciss_get_serial_no(int ctlr, int logvol, +static void cciss_get_serial_no(ctlr_info_t *h, int logvol, unsigned char *serial_no, int buflen) { #define PAGE_83_INQ_BYTES 64 @@ -1880,8 +1880,8 @@ static void cciss_get_serial_no(int ctlr, int logvol, if (!buf) return; memset(serial_no, 0, buflen); - log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); - rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf, + log_unit_to_scsi3addr(h, scsi3addr, logvol); + rc = sendcmd_withirq(h, CISS_INQUIRY, buf, PAGE_83_INQ_BYTES, 0x83, scsi3addr, TYPE_CMD); if (rc == IO_OK) memcpy(serial_no, &buf[8], buflen); @@ -1947,10 +1947,9 @@ init_queue_failure: * is also the controller node. Any changes to disk 0 will show up on * the next reboot. */ -static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, - int via_ioctl) +static void cciss_update_drive_info(ctlr_info_t *h, int drv_index, + int first_time, int via_ioctl) { - ctlr_info_t *h = hba[ctlr]; struct gendisk *disk; InquiryData_struct *inq_buff = NULL; unsigned int block_size; @@ -1967,16 +1966,16 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, /* testing to see if 16-byte CDBs are already being used */ if (h->cciss_read == CCISS_READ_16) { - cciss_read_capacity_16(h->ctlr, drv_index, + cciss_read_capacity_16(h, drv_index, &total_size, &block_size); } else { - cciss_read_capacity(ctlr, drv_index, &total_size, &block_size); + cciss_read_capacity(h, drv_index, &total_size, &block_size); /* if read_capacity returns all F's this volume is >2TB */ /* in size so we switch to 16-byte CDB's for all */ /* read/write ops */ if (total_size == 0xFFFFFFFFULL) { - cciss_read_capacity_16(ctlr, drv_index, + cciss_read_capacity_16(h, drv_index, &total_size, &block_size); h->cciss_read = CCISS_READ_16; h->cciss_write = CCISS_WRITE_16; @@ -1986,14 +1985,14 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, } } - cciss_geometry_inquiry(ctlr, drv_index, total_size, block_size, + cciss_geometry_inquiry(h, drv_index, total_size, block_size, inq_buff, drvinfo); drvinfo->block_size = block_size; drvinfo->nr_blocks = total_size + 1; - cciss_get_device_descr(ctlr, drv_index, drvinfo->vendor, + cciss_get_device_descr(h, drv_index, drvinfo->vendor, drvinfo->model, drvinfo->rev); - cciss_get_serial_no(ctlr, drv_index, drvinfo->serial_no, + cciss_get_serial_no(h, drv_index, drvinfo->serial_no, sizeof(drvinfo->serial_no)); /* Save the lunid in case we deregister the disk, below. */ memcpy(drvinfo->LunID, h->drv[drv_index]->LunID, @@ -2019,9 +2018,9 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time, */ if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { printk(KERN_WARNING "disk %d has changed.\n", drv_index); - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); h->drv[drv_index]->busy_configuring = 1; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); /* deregister_disk sets h->drv[drv_index]->queue = NULL * which keeps the interrupt handler from starting @@ -2243,7 +2242,6 @@ error: static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl) { - int ctlr = h->ctlr; int num_luns; ReportLunData_struct *ld_buff = NULL; int return_code; @@ -2258,19 +2256,19 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, return -EPERM; /* Set busy_configuring flag for this operation */ - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); if (h->busy_configuring) { - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return -EBUSY; } h->busy_configuring = 1; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); if (ld_buff == NULL) goto mem_msg; - return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, + return_code = sendcmd_withirq(h, CISS_REPORT_LOG, ld_buff, sizeof(ReportLunData_struct), 0, CTLR_LUNID, TYPE_CMD); @@ -2317,9 +2315,9 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, } if (!drv_found) { /* Deregister it from the OS, it's gone. */ - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); h->drv[i]->busy_configuring = 1; - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return_code = deregister_disk(h, i, 1, via_ioctl); if (h->drv[i] != NULL) h->drv[i]->busy_configuring = 0; @@ -2358,8 +2356,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, if (drv_index == -1) goto freeret; } - cciss_update_drive_info(ctlr, drv_index, first_time, - via_ioctl); + cciss_update_drive_info(h, drv_index, first_time, via_ioctl); } /* end for */ freeret: @@ -2491,11 +2488,10 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, return 0; } -static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, +static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, int cmd_type) { - ctlr_info_t *h = hba[ctlr]; u64bit buff_dma_handle; int status = IO_OK; @@ -2580,7 +2576,8 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, break; default: printk(KERN_WARNING - "cciss%d: Unknown Command 0x%c\n", ctlr, cmd); + "cciss%d: Unknown Command 0x%c\n", + h->ctlr, cmd); return IO_ERROR; } } else if (cmd_type == TYPE_MSG) { @@ -2613,12 +2610,13 @@ static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, break; default: printk(KERN_WARNING - "cciss%d: unknown message type %d\n", ctlr, cmd); + "cciss%d: unknown message type %d\n", + h->ctlr, cmd); return IO_ERROR; } } else { printk(KERN_WARNING - "cciss%d: unknown command type %d\n", ctlr, cmd_type); + "cciss%d: unknown command type %d\n", h->ctlr, cmd_type); return IO_ERROR; } /* Fill in the scatter gather information */ @@ -2760,18 +2758,17 @@ command_done: return return_status; } -static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, +static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, __u8 page_code, unsigned char scsi3addr[], int cmd_type) { - ctlr_info_t *h = hba[ctlr]; CommandList_struct *c; int return_status; c = cmd_alloc(h, 0); if (!c) return -ENOMEM; - return_status = fill_cmd(c, cmd, ctlr, buff, size, page_code, + return_status = fill_cmd(h, c, cmd, buff, size, page_code, scsi3addr, cmd_type); if (return_status == IO_OK) return_status = sendcmd_withirq_core(h, c, 1); @@ -2780,7 +2777,7 @@ static int sendcmd_withirq(__u8 cmd, int ctlr, void *buff, size_t size, return return_status; } -static void cciss_geometry_inquiry(int ctlr, int logvol, +static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, sector_t total_size, unsigned int block_size, InquiryData_struct *inq_buff, @@ -2791,8 +2788,8 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, unsigned char scsi3addr[8]; memset(inq_buff, 0, sizeof(InquiryData_struct)); - log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); - return_code = sendcmd_withirq(CISS_INQUIRY, ctlr, inq_buff, + log_unit_to_scsi3addr(h, scsi3addr, logvol); + return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff, sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD); if (return_code == IO_OK) { if (inq_buff->data_byte[8] == 0xFF) { @@ -2826,7 +2823,7 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, } static void -cciss_read_capacity(int ctlr, int logvol, sector_t *total_size, +cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size, unsigned int *block_size) { ReadCapdata_struct *buf; @@ -2839,8 +2836,8 @@ cciss_read_capacity(int ctlr, int logvol, sector_t *total_size, return; } - log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); - return_code = sendcmd_withirq(CCISS_READ_CAPACITY, ctlr, buf, + log_unit_to_scsi3addr(h, scsi3addr, logvol); + return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY, buf, sizeof(ReadCapdata_struct), 0, scsi3addr, TYPE_CMD); if (return_code == IO_OK) { *total_size = be32_to_cpu(*(__be32 *) buf->total_size); @@ -2853,7 +2850,7 @@ cciss_read_capacity(int ctlr, int logvol, sector_t *total_size, kfree(buf); } -static void cciss_read_capacity_16(int ctlr, int logvol, +static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, sector_t *total_size, unsigned int *block_size) { ReadCapdata_struct_16 *buf; @@ -2866,9 +2863,9 @@ static void cciss_read_capacity_16(int ctlr, int logvol, return; } - log_unit_to_scsi3addr(hba[ctlr], scsi3addr, logvol); - return_code = sendcmd_withirq(CCISS_READ_CAPACITY_16, - ctlr, buf, sizeof(ReadCapdata_struct_16), + log_unit_to_scsi3addr(h, scsi3addr, logvol); + return_code = sendcmd_withirq(h, CCISS_READ_CAPACITY_16, + buf, sizeof(ReadCapdata_struct_16), 0, scsi3addr, TYPE_CMD); if (return_code == IO_OK) { *total_size = be64_to_cpu(*(__be64 *) buf->total_size); @@ -2910,13 +2907,13 @@ static int cciss_revalidate(struct gendisk *disk) return 1; } if (h->cciss_read == CCISS_READ_10) { - cciss_read_capacity(h->ctlr, logvol, + cciss_read_capacity(h, logvol, &total_size, &block_size); } else { - cciss_read_capacity_16(h->ctlr, logvol, + cciss_read_capacity_16(h, logvol, &total_size, &block_size); } - cciss_geometry_inquiry(h->ctlr, logvol, total_size, block_size, + cciss_geometry_inquiry(h, logvol, total_size, block_size, inq_buff, drv); blk_queue_logical_block_size(drv->queue, drv->block_size); @@ -2966,7 +2963,7 @@ static void start_io(ctlr_info_t *h) } } -/* Assumes that CCISS_LOCK(h->ctlr) is held. */ +/* Assumes that h->lock is held. */ /* Zeros out the error record and then resends the command back */ /* to the controller */ static inline void resend_cciss_cmd(ctlr_info_t *h, CommandList_struct *c) @@ -3494,7 +3491,7 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id) * If there are completed commands in the completion queue, * we had better do something about it. */ - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); while (interrupt_pending(h)) { raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) { @@ -3505,7 +3502,7 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id) } } - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } @@ -3524,7 +3521,7 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) * If there are completed commands in the completion queue, * we had better do something about it. */ - spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) { if (cciss_tag_contains_index(raw_tag)) @@ -3533,7 +3530,7 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) raw_tag = process_nonindexed_cmd(h, raw_tag); } - spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } @@ -3961,7 +3958,7 @@ clean_up: * controllers that are capable. If not, we use IO-APIC mode. */ -static void __devinit cciss_interrupt_mode(ctlr_info_t *c) +static void __devinit cciss_interrupt_mode(ctlr_info_t *h) { #ifdef CONFIG_PCI_MSI int err; @@ -3970,18 +3967,18 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c) }; /* Some boards advertise MSI but don't really support it */ - if ((c->board_id == 0x40700E11) || (c->board_id == 0x40800E11) || - (c->board_id == 0x40820E11) || (c->board_id == 0x40830E11)) + if ((h->board_id == 0x40700E11) || (h->board_id == 0x40800E11) || + (h->board_id == 0x40820E11) || (h->board_id == 0x40830E11)) goto default_int_mode; - if (pci_find_capability(c->pdev, PCI_CAP_ID_MSIX)) { - err = pci_enable_msix(c->pdev, cciss_msix_entries, 4); + if (pci_find_capability(h->pdev, PCI_CAP_ID_MSIX)) { + err = pci_enable_msix(h->pdev, cciss_msix_entries, 4); if (!err) { - c->intr[0] = cciss_msix_entries[0].vector; - c->intr[1] = cciss_msix_entries[1].vector; - c->intr[2] = cciss_msix_entries[2].vector; - c->intr[3] = cciss_msix_entries[3].vector; - c->msix_vector = 1; + h->intr[0] = cciss_msix_entries[0].vector; + h->intr[1] = cciss_msix_entries[1].vector; + h->intr[2] = cciss_msix_entries[2].vector; + h->intr[3] = cciss_msix_entries[3].vector; + h->msix_vector = 1; return; } if (err > 0) { @@ -3994,17 +3991,16 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *c) goto default_int_mode; } } - if (pci_find_capability(c->pdev, PCI_CAP_ID_MSI)) { - if (!pci_enable_msi(c->pdev)) { - c->msi_vector = 1; - } else { + if (pci_find_capability(h->pdev, PCI_CAP_ID_MSI)) { + if (!pci_enable_msi(h->pdev)) + h->msi_vector = 1; + else printk(KERN_WARNING "cciss: MSI init failed\n"); - } } default_int_mode: #endif /* CONFIG_PCI_MSI */ /* if we get here we're going to use the default interrupt mode */ - c->intr[PERF_MODE_INT] = c->pdev->irq; + h->intr[PERF_MODE_INT] = h->pdev->irq; return; } @@ -4190,28 +4186,28 @@ static inline void cciss_p600_dma_prefetch_quirk(ctlr_info_t *h) pci_write_config_dword(h->pdev, PCI_COMMAND_PARITY, dma_refetch); } -static int __devinit cciss_pci_init(ctlr_info_t *c) +static int __devinit cciss_pci_init(ctlr_info_t *h) { int prod_index, err; - prod_index = cciss_lookup_board_id(c->pdev, &c->board_id); + prod_index = cciss_lookup_board_id(h->pdev, &h->board_id); if (prod_index < 0) return -ENODEV; - c->product_name = products[prod_index].product_name; - c->access = *(products[prod_index].access); + h->product_name = products[prod_index].product_name; + h->access = *(products[prod_index].access); - if (cciss_board_disabled(c)) { + if (cciss_board_disabled(h)) { printk(KERN_WARNING "cciss: controller appears to be disabled\n"); return -ENODEV; } - err = pci_enable_device(c->pdev); + err = pci_enable_device(h->pdev); if (err) { printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); return err; } - err = pci_request_regions(c->pdev, "cciss"); + err = pci_request_regions(h->pdev, "cciss"); if (err) { printk(KERN_ERR "cciss: Cannot obtain PCI resources, " "aborting\n"); @@ -4220,38 +4216,38 @@ static int __devinit cciss_pci_init(ctlr_info_t *c) #ifdef CCISS_DEBUG printk(KERN_INFO "command = %x\n", command); - printk(KERN_INFO "irq = %x\n", c->pdev->irq); - printk(KERN_INFO "board_id = %x\n", c->board_id); + printk(KERN_INFO "irq = %x\n", h->pdev->irq); + printk(KERN_INFO "board_id = %x\n", h->board_id); #endif /* CCISS_DEBUG */ /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. */ - cciss_interrupt_mode(c); - err = cciss_pci_find_memory_BAR(c->pdev, &c->paddr); + cciss_interrupt_mode(h); + err = cciss_pci_find_memory_BAR(h->pdev, &h->paddr); if (err) goto err_out_free_res; - c->vaddr = remap_pci_mem(c->paddr, 0x250); - if (!c->vaddr) { + h->vaddr = remap_pci_mem(h->paddr, 0x250); + if (!h->vaddr) { err = -ENOMEM; goto err_out_free_res; } - err = cciss_wait_for_board_ready(c); + err = cciss_wait_for_board_ready(h); if (err) goto err_out_free_res; - err = cciss_find_cfgtables(c); + err = cciss_find_cfgtables(h); if (err) goto err_out_free_res; - print_cfg_table(c->cfgtable); - cciss_find_board_params(c); + print_cfg_table(h->cfgtable); + cciss_find_board_params(h); - if (!CISS_signature_present(c)) { + if (!CISS_signature_present(h)) { err = -ENODEV; goto err_out_free_res; } - cciss_enable_scsi_prefetch(c); - cciss_p600_dma_prefetch_quirk(c); - cciss_put_controller_into_performant_mode(c); + cciss_enable_scsi_prefetch(h); + cciss_p600_dma_prefetch_quirk(h); + cciss_put_controller_into_performant_mode(h); return 0; err_out_free_res: @@ -4259,13 +4255,13 @@ err_out_free_res: * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo */ - if (c->transtable) - iounmap(c->transtable); - if (c->cfgtable) - iounmap(c->cfgtable); - if (c->vaddr) - iounmap(c->vaddr); - pci_release_regions(c->pdev); + if (h->transtable) + iounmap(h->transtable); + if (h->cfgtable) + iounmap(h->cfgtable); + if (h->vaddr) + iounmap(h->vaddr); + pci_release_regions(h->pdev); return err; } @@ -4278,12 +4274,12 @@ static int alloc_cciss_hba(void) for (i = 0; i < MAX_CTLR; i++) { if (!hba[i]) { - ctlr_info_t *p; + ctlr_info_t *h; - p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); - if (!p) + h = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); + if (!h) goto Enomem; - hba[i] = p; + hba[i] = h; return i; } } @@ -4295,12 +4291,11 @@ Enomem: return -1; } -static void free_hba(int n) +static void free_hba(ctlr_info_t *h) { - ctlr_info_t *h = hba[n]; int i; - hba[n] = NULL; + hba[h->ctlr] = NULL; for (i = 0; i < h->highest_lun + 1; i++) if (h->gendisk[i] != NULL) put_disk(h->gendisk[i]); @@ -4651,6 +4646,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, int rc; int dac, return_code; InquiryData_struct *inq_buff; + ctlr_info_t *h; rc = cciss_init_reset_devices(pdev); if (rc) @@ -4659,21 +4655,22 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, if (i < 0) return -1; - hba[i]->pdev = pdev; - hba[i]->busy_initializing = 1; - INIT_HLIST_HEAD(&hba[i]->cmpQ); - INIT_HLIST_HEAD(&hba[i]->reqQ); - mutex_init(&hba[i]->busy_shutting_down); + h = hba[i]; + h->pdev = pdev; + h->busy_initializing = 1; + INIT_HLIST_HEAD(&h->cmpQ); + INIT_HLIST_HEAD(&h->reqQ); + mutex_init(&h->busy_shutting_down); - if (cciss_pci_init(hba[i]) != 0) + if (cciss_pci_init(h) != 0) goto clean_no_release_regions; - sprintf(hba[i]->devname, "cciss%d", i); - hba[i]->ctlr = i; + sprintf(h->devname, "cciss%d", i); + h->ctlr = i; - init_completion(&hba[i]->scan_wait); + init_completion(&h->scan_wait); - if (cciss_create_hba_sysfs_entry(hba[i])) + if (cciss_create_hba_sysfs_entry(h)) goto clean0; /* configure PCI DMA stuff */ @@ -4692,100 +4689,100 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, * 8 controller support. */ if (i < MAX_CTLR_ORIG) - hba[i]->major = COMPAQ_CISS_MAJOR + i; - rc = register_blkdev(hba[i]->major, hba[i]->devname); + h->major = COMPAQ_CISS_MAJOR + i; + rc = register_blkdev(h->major, h->devname); if (rc == -EBUSY || rc == -EINVAL) { printk(KERN_ERR "cciss: Unable to get major number %d for %s " - "on hba %d\n", hba[i]->major, hba[i]->devname, i); + "on hba %d\n", h->major, h->devname, i); goto clean1; } else { if (i >= MAX_CTLR_ORIG) - hba[i]->major = rc; + h->major = rc; } /* make sure the board interrupts are off */ - hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_OFF); - if (hba[i]->msi_vector || hba[i]->msix_vector) { - if (request_irq(hba[i]->intr[PERF_MODE_INT], + h->access.set_intr_mask(h, CCISS_INTR_OFF); + if (h->msi_vector || h->msix_vector) { + if (request_irq(h->intr[PERF_MODE_INT], do_cciss_msix_intr, - IRQF_DISABLED, hba[i]->devname, hba[i])) { + IRQF_DISABLED, h->devname, h)) { printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", - hba[i]->intr[PERF_MODE_INT], hba[i]->devname); + h->intr[PERF_MODE_INT], h->devname); goto clean2; } } else { - if (request_irq(hba[i]->intr[PERF_MODE_INT], do_cciss_intx, - IRQF_DISABLED, hba[i]->devname, hba[i])) { + if (request_irq(h->intr[PERF_MODE_INT], do_cciss_intx, + IRQF_DISABLED, h->devname, h)) { printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", - hba[i]->intr[PERF_MODE_INT], hba[i]->devname); + h->intr[PERF_MODE_INT], h->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[PERF_MODE_INT], dac ? "" : " not"); + h->devname, pdev->device, pci_name(pdev), + h->intr[PERF_MODE_INT], dac ? "" : " not"); - hba[i]->cmd_pool_bits = - kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) + h->cmd_pool_bits = + kmalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); - hba[i]->cmd_pool = (CommandList_struct *) - pci_alloc_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(CommandList_struct), - &(hba[i]->cmd_pool_dhandle)); - hba[i]->errinfo_pool = (ErrorInfo_struct *) - pci_alloc_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(ErrorInfo_struct), - &(hba[i]->errinfo_pool_dhandle)); - if ((hba[i]->cmd_pool_bits == NULL) - || (hba[i]->cmd_pool == NULL) - || (hba[i]->errinfo_pool == NULL)) { + h->cmd_pool = (CommandList_struct *) + pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(CommandList_struct), + &(h->cmd_pool_dhandle)); + h->errinfo_pool = (ErrorInfo_struct *) + pci_alloc_consistent(h->pdev, + h->nr_cmds * sizeof(ErrorInfo_struct), + &(h->errinfo_pool_dhandle)); + if ((h->cmd_pool_bits == NULL) + || (h->cmd_pool == NULL) + || (h->errinfo_pool == NULL)) { printk(KERN_ERR "cciss: out of memory"); goto clean4; } /* Need space for temp scatter list */ - hba[i]->scatter_list = kmalloc(hba[i]->max_commands * + h->scatter_list = kmalloc(h->max_commands * sizeof(struct scatterlist *), GFP_KERNEL); - for (k = 0; k < hba[i]->nr_cmds; k++) { - hba[i]->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * - hba[i]->maxsgentries, + for (k = 0; k < h->nr_cmds; k++) { + h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * + h->maxsgentries, GFP_KERNEL); - if (hba[i]->scatter_list[k] == NULL) { + if (h->scatter_list[k] == NULL) { printk(KERN_ERR "cciss%d: could not allocate " "s/g lists\n", i); goto clean4; } } - hba[i]->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[i], - hba[i]->chainsize, hba[i]->nr_cmds); - if (!hba[i]->cmd_sg_list && hba[i]->chainsize > 0) + h->cmd_sg_list = cciss_allocate_sg_chain_blocks(h, + h->chainsize, h->nr_cmds); + if (!h->cmd_sg_list && h->chainsize > 0) goto clean4; - spin_lock_init(&hba[i]->lock); + spin_lock_init(&h->lock); /* Initialize the pdev driver private data. - have it point to hba[i]. */ - pci_set_drvdata(pdev, hba[i]); + have it point to h. */ + pci_set_drvdata(pdev, h); /* command and error info recs zeroed out before they are used */ - memset(hba[i]->cmd_pool_bits, 0, - DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) + memset(h->cmd_pool_bits, 0, + DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) * sizeof(unsigned long)); - hba[i]->num_luns = 0; - hba[i]->highest_lun = -1; + h->num_luns = 0; + h->highest_lun = -1; for (j = 0; j < CISS_MAX_LUN; j++) { - hba[i]->drv[j] = NULL; - hba[i]->gendisk[j] = NULL; + h->drv[j] = NULL; + h->gendisk[j] = NULL; } - cciss_scsi_setup(i); + cciss_scsi_setup(h); /* Turn the interrupts on so we can service requests */ - hba[i]->access.set_intr_mask(hba[i], CCISS_INTR_ON); + h->access.set_intr_mask(h, CCISS_INTR_ON); /* Get the firmware version */ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); @@ -4794,59 +4791,59 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, goto clean4; } - return_code = sendcmd_withirq(CISS_INQUIRY, i, inq_buff, + return_code = sendcmd_withirq(h, CISS_INQUIRY, inq_buff, sizeof(InquiryData_struct), 0, CTLR_LUNID, TYPE_CMD); if (return_code == IO_OK) { - hba[i]->firm_ver[0] = inq_buff->data_byte[32]; - hba[i]->firm_ver[1] = inq_buff->data_byte[33]; - hba[i]->firm_ver[2] = inq_buff->data_byte[34]; - hba[i]->firm_ver[3] = inq_buff->data_byte[35]; + h->firm_ver[0] = inq_buff->data_byte[32]; + h->firm_ver[1] = inq_buff->data_byte[33]; + h->firm_ver[2] = inq_buff->data_byte[34]; + h->firm_ver[3] = inq_buff->data_byte[35]; } else { /* send command failed */ printk(KERN_WARNING "cciss: unable to determine firmware" " version of controller\n"); } kfree(inq_buff); - cciss_procinit(i); + cciss_procinit(h); - hba[i]->cciss_max_sectors = 8192; + h->cciss_max_sectors = 8192; - rebuild_lun_table(hba[i], 1, 0); - hba[i]->busy_initializing = 0; + rebuild_lun_table(h, 1, 0); + h->busy_initializing = 0; return 1; clean4: - kfree(hba[i]->cmd_pool_bits); + kfree(h->cmd_pool_bits); /* Free up sg elements */ - for (k = 0; k < hba[i]->nr_cmds; k++) - kfree(hba[i]->scatter_list[k]); - kfree(hba[i]->scatter_list); - cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); - if (hba[i]->cmd_pool) - pci_free_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(CommandList_struct), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - if (hba[i]->errinfo_pool) - pci_free_consistent(hba[i]->pdev, - hba[i]->nr_cmds * sizeof(ErrorInfo_struct), - hba[i]->errinfo_pool, - hba[i]->errinfo_pool_dhandle); - free_irq(hba[i]->intr[PERF_MODE_INT], hba[i]); + for (k = 0; k < h->nr_cmds; k++) + kfree(h->scatter_list[k]); + kfree(h->scatter_list); + cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); + if (h->cmd_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(CommandList_struct), + h->cmd_pool, h->cmd_pool_dhandle); + if (h->errinfo_pool) + pci_free_consistent(h->pdev, + h->nr_cmds * sizeof(ErrorInfo_struct), + h->errinfo_pool, + h->errinfo_pool_dhandle); + free_irq(h->intr[PERF_MODE_INT], h); clean2: - unregister_blkdev(hba[i]->major, hba[i]->devname); + unregister_blkdev(h->major, h->devname); clean1: - cciss_destroy_hba_sysfs_entry(hba[i]); + cciss_destroy_hba_sysfs_entry(h); clean0: pci_release_regions(pdev); clean_no_release_regions: - hba[i]->busy_initializing = 0; + h->busy_initializing = 0; /* * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo */ pci_set_drvdata(pdev, NULL); - free_hba(i); + free_hba(h); return -1; } @@ -4866,7 +4863,7 @@ static void cciss_shutdown(struct pci_dev *pdev) } /* write all data in the battery backed cache to disk */ memset(flush_buf, 0, 4); - return_code = sendcmd_withirq(CCISS_CACHE_FLUSH, h->ctlr, flush_buf, + return_code = sendcmd_withirq(h, CCISS_CACHE_FLUSH, flush_buf, 4, 0, CTLR_LUNID, TYPE_CMD); kfree(flush_buf); if (return_code != IO_OK) @@ -4878,7 +4875,7 @@ static void cciss_shutdown(struct pci_dev *pdev) static void __devexit cciss_remove_one(struct pci_dev *pdev) { - ctlr_info_t *tmp_ptr; + ctlr_info_t *h; int i, j; if (pci_get_drvdata(pdev) == NULL) { @@ -4886,28 +4883,28 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) return; } - tmp_ptr = pci_get_drvdata(pdev); - i = tmp_ptr->ctlr; + h = pci_get_drvdata(pdev); + i = h->ctlr; if (hba[i] == NULL) { printk(KERN_ERR "cciss: device appears to " - "already be removed \n"); + "already be removed\n"); return; } - mutex_lock(&hba[i]->busy_shutting_down); + mutex_lock(&h->busy_shutting_down); - remove_from_scan_list(hba[i]); - remove_proc_entry(hba[i]->devname, proc_cciss); - unregister_blkdev(hba[i]->major, hba[i]->devname); + remove_from_scan_list(h); + remove_proc_entry(h->devname, proc_cciss); + unregister_blkdev(h->major, h->devname); /* remove it from the disk list */ for (j = 0; j < CISS_MAX_LUN; j++) { - struct gendisk *disk = hba[i]->gendisk[j]; + struct gendisk *disk = h->gendisk[j]; if (disk) { struct request_queue *q = disk->queue; if (disk->flags & GENHD_FL_UP) { - cciss_destroy_ld_sysfs_entry(hba[i], j, 1); + cciss_destroy_ld_sysfs_entry(h, j, 1); del_gendisk(disk); } if (q) @@ -4916,41 +4913,41 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) } #ifdef CONFIG_CISS_SCSI_TAPE - cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ + cciss_unregister_scsi(h); /* unhook from SCSI subsystem */ #endif cciss_shutdown(pdev); #ifdef CONFIG_PCI_MSI - if (hba[i]->msix_vector) - pci_disable_msix(hba[i]->pdev); - else if (hba[i]->msi_vector) - pci_disable_msi(hba[i]->pdev); + if (h->msix_vector) + pci_disable_msix(h->pdev); + else if (h->msi_vector) + pci_disable_msi(h->pdev); #endif /* CONFIG_PCI_MSI */ - iounmap(hba[i]->transtable); - iounmap(hba[i]->cfgtable); - iounmap(hba[i]->vaddr); + iounmap(h->transtable); + iounmap(h->cfgtable); + iounmap(h->vaddr); - pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(CommandList_struct), - hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle); - pci_free_consistent(hba[i]->pdev, hba[i]->nr_cmds * sizeof(ErrorInfo_struct), - hba[i]->errinfo_pool, hba[i]->errinfo_pool_dhandle); - kfree(hba[i]->cmd_pool_bits); + pci_free_consistent(h->pdev, h->nr_cmds * sizeof(CommandList_struct), + h->cmd_pool, h->cmd_pool_dhandle); + pci_free_consistent(h->pdev, h->nr_cmds * sizeof(ErrorInfo_struct), + h->errinfo_pool, h->errinfo_pool_dhandle); + kfree(h->cmd_pool_bits); /* Free up sg elements */ - for (j = 0; j < hba[i]->nr_cmds; j++) - kfree(hba[i]->scatter_list[j]); - kfree(hba[i]->scatter_list); - cciss_free_sg_chain_blocks(hba[i]->cmd_sg_list, hba[i]->nr_cmds); + for (j = 0; j < h->nr_cmds; j++) + kfree(h->scatter_list[j]); + kfree(h->scatter_list); + cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); /* * Deliberately omit pci_disable_device(): it does something nasty to * Smart Array controllers that pci_enable_device does not undo */ pci_release_regions(pdev); pci_set_drvdata(pdev, NULL); - cciss_destroy_hba_sysfs_entry(hba[i]); - mutex_unlock(&hba[i]->busy_shutting_down); - free_hba(i); + cciss_destroy_hba_sysfs_entry(h); + mutex_unlock(&h->busy_shutting_down); + free_hba(h); } static struct pci_driver cciss_pci_driver = { diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index 4290b7f0f63..ae340ffc8f8 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h @@ -419,6 +419,4 @@ struct board_type { int nr_cmds; /* Max cmds this kind of ctlr can handle. */ }; -#define CCISS_LOCK(i) (&hba[i]->lock) - #endif /* CCISS_H */ diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 3604b72f2af..9133ad4c7b1 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -44,7 +44,7 @@ #define CCISS_ABORT_MSG 0x00 #define CCISS_RESET_MSG 0x01 -static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff, +static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, size_t size, __u8 page_code, unsigned char *scsi3addr, int cmd_type); @@ -127,16 +127,16 @@ struct cciss_scsi_adapter_data_t { spinlock_t lock; // to protect ccissscsi[ctlr]; }; -#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \ - &hba[ctlr]->scsi_ctlr->lock, flags); -#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \ - &hba[ctlr]->scsi_ctlr->lock, flags); +#define CPQ_TAPE_LOCK(h, flags) spin_lock_irqsave( \ + &h->scsi_ctlr->lock, flags); +#define CPQ_TAPE_UNLOCK(h, flags) spin_unlock_irqrestore( \ + &h->scsi_ctlr->lock, flags); static CommandList_struct * scsi_cmd_alloc(ctlr_info_t *h) { /* assume only one process in here at a time, locking done by caller. */ - /* use CCISS_LOCK(ctlr) */ + /* use h->lock */ /* might be better to rewrite how we allocate scsi commands in a way that */ /* needs no locking at all. */ @@ -177,10 +177,10 @@ scsi_cmd_alloc(ctlr_info_t *h) } static void -scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) +scsi_cmd_free(ctlr_info_t *h, CommandList_struct *c) { /* assume only one process in here at a time, locking done by caller. */ - /* use CCISS_LOCK(ctlr) */ + /* use h->lock */ /* drop the free memory chunk on top of the stack. */ struct cciss_scsi_adapter_data_t *sa; @@ -193,19 +193,19 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd) printk("cciss: scsi_cmd_free called too many times.\n"); BUG(); } - stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd; + stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) c; } static int -scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) +scsi_cmd_stack_setup(ctlr_info_t *h, struct cciss_scsi_adapter_data_t *sa) { int i; struct cciss_scsi_cmd_stack_t *stk; size_t size; - sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(hba[ctlr], - hba[ctlr]->chainsize, CMD_STACK_SIZE); - if (!sa->cmd_sg_list && hba[ctlr]->chainsize > 0) + sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(h, + h->chainsize, CMD_STACK_SIZE); + if (!sa->cmd_sg_list && h->chainsize > 0) return -ENOMEM; stk = &sa->cmd_stack; @@ -215,7 +215,7 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0); /* pci_alloc_consistent guarantees 32-bit DMA address will be used */ stk->pool = (struct cciss_scsi_cmd_stack_elem_t *) - pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle); + pci_alloc_consistent(h->pdev, size, &stk->cmd_pool_handle); if (stk->pool == NULL) { cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); @@ -234,13 +234,13 @@ scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa) } static void -scsi_cmd_stack_free(int ctlr) +scsi_cmd_stack_free(ctlr_info_t *h) { struct cciss_scsi_adapter_data_t *sa; struct cciss_scsi_cmd_stack_t *stk; size_t size; - sa = hba[ctlr]->scsi_ctlr; + sa = h->scsi_ctlr; stk = &sa->cmd_stack; if (stk->top != CMD_STACK_SIZE-1) { printk( "cciss: %d scsi commands are still outstanding.\n", @@ -250,7 +250,7 @@ scsi_cmd_stack_free(int ctlr) } size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; - pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle); + pci_free_consistent(h->pdev, size, stk->pool, stk->cmd_pool_handle); stk->pool = NULL; cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE); } @@ -342,20 +342,20 @@ print_cmd(CommandList_struct *cp) #endif static int -find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) +find_bus_target_lun(ctlr_info_t *h, int *bus, int *target, int *lun) { /* finds an unused bus, target, lun for a new device */ - /* assumes hba[ctlr]->scsi_ctlr->lock is held */ + /* assumes h->scsi_ctlr->lock is held */ int i, found=0; unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA]; memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA); target_taken[SELF_SCSI_ID] = 1; - for (i=0;ictlr].ndevices; i++) + target_taken[ccissscsi[h->ctlr].dev[i].target] = 1; - for (i=0;iscsi_ctlr->lock is held */ - int n = ccissscsi[ctlr].ndevices; + /* assumes h->scsi_ctlr->lock is held */ + int n = ccissscsi[h->ctlr].ndevices; struct cciss_scsi_dev_t *sd; int i, bus, target, lun; unsigned char addr1[8], addr2[8]; if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { printk("cciss%d: Too many devices, " - "some will be inaccessible.\n", ctlr); + "some will be inaccessible.\n", h->ctlr); return -1; } @@ -397,7 +397,7 @@ cciss_scsi_add_entry(int ctlr, int hostno, memcpy(addr1, device->scsi3addr, 8); addr1[4] = 0; for (i = 0; i < n; i++) { - sd = &ccissscsi[ctlr].dev[i]; + sd = &ccissscsi[h->ctlr].dev[i]; memcpy(addr2, sd->scsi3addr, 8); addr2[4] = 0; /* differ only in byte 4? */ @@ -410,9 +410,9 @@ cciss_scsi_add_entry(int ctlr, int hostno, } } - sd = &ccissscsi[ctlr].dev[n]; + sd = &ccissscsi[h->ctlr].dev[n]; if (lun == 0) { - if (find_bus_target_lun(ctlr, + if (find_bus_target_lun(h, &sd->bus, &sd->target, &sd->lun) != 0) return -1; } else { @@ -431,37 +431,37 @@ cciss_scsi_add_entry(int ctlr, int hostno, memcpy(sd->device_id, device->device_id, sizeof(sd->device_id)); sd->devtype = device->devtype; - ccissscsi[ctlr].ndevices++; + ccissscsi[h->ctlr].ndevices++; /* initially, (before registering with scsi layer) we don't know our hostno and we don't want to print anything first time anyway (the scsi layer's inquiries will show that info) */ if (hostno != -1) printk("cciss%d: %s device c%db%dt%dl%d added.\n", - ctlr, scsi_device_type(sd->devtype), hostno, + h->ctlr, scsi_device_type(sd->devtype), hostno, sd->bus, sd->target, sd->lun); return 0; } static void -cciss_scsi_remove_entry(int ctlr, int hostno, int entry, +cciss_scsi_remove_entry(ctlr_info_t *h, int hostno, int entry, struct scsi2map *removed, int *nremoved) { - /* assumes hba[ctlr]->scsi_ctlr->lock is held */ + /* assumes h->ctlr]->scsi_ctlr->lock is held */ int i; struct cciss_scsi_dev_t sd; if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; - sd = ccissscsi[ctlr].dev[entry]; + sd = ccissscsi[h->ctlr].dev[entry]; removed[*nremoved].bus = sd.bus; removed[*nremoved].target = sd.target; removed[*nremoved].lun = sd.lun; (*nremoved)++; - for (i=entry;ictlr].ndevices-1; i++) + ccissscsi[h->ctlr].dev[i] = ccissscsi[h->ctlr].dev[i+1]; + ccissscsi[h->ctlr].ndevices--; printk("cciss%d: %s device c%db%dt%dl%d removed.\n", - ctlr, scsi_device_type(sd.devtype), hostno, + h->ctlr, scsi_device_type(sd.devtype), hostno, sd.bus, sd.target, sd.lun); } @@ -476,24 +476,24 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry, (a)[1] == (b)[1] && \ (a)[0] == (b)[0]) -static void fixup_botched_add(int ctlr, char *scsi3addr) +static void fixup_botched_add(ctlr_info_t *h, char *scsi3addr) { /* called when scsi_add_device fails in order to re-adjust */ /* ccissscsi[] to match the mid layer's view. */ unsigned long flags; int i, j; - CPQ_TAPE_LOCK(ctlr, flags); - for (i = 0; i < ccissscsi[ctlr].ndevices; i++) { + CPQ_TAPE_LOCK(h, flags); + for (i = 0; i < ccissscsi[h->ctlr].ndevices; i++) { if (memcmp(scsi3addr, - ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) { - for (j = i; j < ccissscsi[ctlr].ndevices-1; j++) - ccissscsi[ctlr].dev[j] = - ccissscsi[ctlr].dev[j+1]; - ccissscsi[ctlr].ndevices--; + ccissscsi[h->ctlr].dev[i].scsi3addr, 8) == 0) { + for (j = i; j < ccissscsi[h->ctlr].ndevices-1; j++) + ccissscsi[h->ctlr].dev[j] = + ccissscsi[h->ctlr].dev[j+1]; + ccissscsi[h->ctlr].ndevices--; break; } } - CPQ_TAPE_UNLOCK(ctlr, flags); + CPQ_TAPE_UNLOCK(h, flags); } static int device_is_the_same(struct cciss_scsi_dev_t *dev1, @@ -513,7 +513,7 @@ static int device_is_the_same(struct cciss_scsi_dev_t *dev1, } static int -adjust_cciss_scsi_table(int ctlr, int hostno, +adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, struct cciss_scsi_dev_t sd[], int nsds) { /* sd contains scsi3 addresses and devtypes, but @@ -535,14 +535,14 @@ adjust_cciss_scsi_table(int ctlr, int hostno, if (!added || !removed) { printk(KERN_WARNING "cciss%d: Out of memory in " - "adjust_cciss_scsi_table\n", ctlr); + "adjust_cciss_scsi_table\n", h->ctlr); goto free_and_out; } - CPQ_TAPE_LOCK(ctlr, flags); + CPQ_TAPE_LOCK(h, flags); if (hostno != -1) /* if it's not the first time... */ - sh = hba[ctlr]->scsi_ctlr->scsi_host; + sh = h->scsi_ctlr->scsi_host; /* find any devices in ccissscsi[] that are not in sd[] and remove them from ccissscsi[] */ @@ -550,8 +550,8 @@ adjust_cciss_scsi_table(int ctlr, int hostno, i = 0; nremoved = 0; nadded = 0; - while(ictlr].ndevices) { + csd = &ccissscsi[h->ctlr].dev[i]; found=0; for (j=0;jdevtype), hostno, + h->ctlr, scsi_device_type(csd->devtype), hostno, csd->bus, csd->target, csd->lun); */ - cciss_scsi_remove_entry(ctlr, hostno, i, + cciss_scsi_remove_entry(h, hostno, i, removed, &nremoved); /* remove ^^^, hence i not incremented */ } else if (found == 1) { /* device is different in some way */ changes++; printk("cciss%d: device c%db%dt%dl%d has changed.\n", - ctlr, hostno, csd->bus, csd->target, csd->lun); - cciss_scsi_remove_entry(ctlr, hostno, i, + h->ctlr, hostno, + csd->bus, csd->target, csd->lun); + cciss_scsi_remove_entry(h, hostno, i, removed, &nremoved); /* remove ^^^, hence i not incremented */ - if (cciss_scsi_add_entry(ctlr, hostno, &sd[j], + if (cciss_scsi_add_entry(h, hostno, &sd[j], added, &nadded) != 0) /* we just removed one, so add can't fail. */ BUG(); @@ -601,8 +602,8 @@ adjust_cciss_scsi_table(int ctlr, int hostno, for (i=0;ictlr].ndevices; j++) { + csd = &ccissscsi[h->ctlr].dev[j]; if (SCSI3ADDR_EQ(sd[i].scsi3addr, csd->scsi3addr)) { if (device_is_the_same(&sd[i], csd)) @@ -614,18 +615,18 @@ adjust_cciss_scsi_table(int ctlr, int hostno, } if (!found) { changes++; - if (cciss_scsi_add_entry(ctlr, hostno, &sd[i], + if (cciss_scsi_add_entry(h, hostno, &sd[i], added, &nadded) != 0) break; } else if (found == 1) { /* should never happen... */ changes++; printk(KERN_WARNING "cciss%d: device " - "unexpectedly changed\n", ctlr); + "unexpectedly changed\n", h->ctlr); /* but if it does happen, we just ignore that device */ } } - CPQ_TAPE_UNLOCK(ctlr, flags); + CPQ_TAPE_UNLOCK(h, flags); /* Don't notify scsi mid layer of any changes the first time through */ /* (or if there are no changes) scsi_scan_host will do it later the */ @@ -647,7 +648,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno, /* timeout as if the device was gone. */ printk(KERN_WARNING "cciss%d: didn't find " "c%db%dt%dl%d\n for removal.", - ctlr, hostno, removed[i].bus, + h->ctlr, hostno, removed[i].bus, removed[i].target, removed[i].lun); } } @@ -661,11 +662,11 @@ adjust_cciss_scsi_table(int ctlr, int hostno, continue; printk(KERN_WARNING "cciss%d: scsi_add_device " "c%db%dt%dl%d failed, device not added.\n", - ctlr, hostno, + h->ctlr, hostno, added[i].bus, added[i].target, added[i].lun); /* now we have to remove it from ccissscsi, */ /* since it didn't get added to scsi mid layer */ - fixup_botched_add(ctlr, added[i].scsi3addr); + fixup_botched_add(h, added[i].scsi3addr); } free_and_out: @@ -675,33 +676,33 @@ free_and_out: } static int -lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr) +lookup_scsi3addr(ctlr_info_t *h, int bus, int target, int lun, char *scsi3addr) { int i; struct cciss_scsi_dev_t *sd; unsigned long flags; - CPQ_TAPE_LOCK(ctlr, flags); - for (i=0;ictlr].ndevices; i++) { + sd = &ccissscsi[h->ctlr].dev[i]; if (sd->bus == bus && sd->target == target && sd->lun == lun) { memcpy(scsi3addr, &sd->scsi3addr[0], 8); - CPQ_TAPE_UNLOCK(ctlr, flags); + CPQ_TAPE_UNLOCK(h, flags); return 0; } } - CPQ_TAPE_UNLOCK(ctlr, flags); + CPQ_TAPE_UNLOCK(h, flags); return -1; } static void -cciss_scsi_setup(int cntl_num) +cciss_scsi_setup(ctlr_info_t *h) { struct cciss_scsi_adapter_data_t * shba; - ccissscsi[cntl_num].ndevices = 0; + ccissscsi[h->ctlr].ndevices = 0; shba = (struct cciss_scsi_adapter_data_t *) kmalloc(sizeof(*shba), GFP_KERNEL); if (shba == NULL) @@ -709,35 +710,35 @@ cciss_scsi_setup(int cntl_num) shba->scsi_host = NULL; spin_lock_init(&shba->lock); shba->registered = 0; - if (scsi_cmd_stack_setup(cntl_num, shba) != 0) { + if (scsi_cmd_stack_setup(h, shba) != 0) { kfree(shba); shba = NULL; } - hba[cntl_num]->scsi_ctlr = shba; + h->scsi_ctlr = shba; return; } -static void -complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) +static void complete_scsi_command(CommandList_struct *c, int timeout, + __u32 tag) { struct scsi_cmnd *cmd; - ctlr_info_t *ctlr; + ctlr_info_t *h; ErrorInfo_struct *ei; - ei = cp->err_info; + ei = c->err_info; /* First, see if it was a message rather than a command */ - if (cp->Request.Type.Type == TYPE_MSG) { - cp->cmd_type = CMD_MSG_DONE; + if (c->Request.Type.Type == TYPE_MSG) { + c->cmd_type = CMD_MSG_DONE; return; } - cmd = (struct scsi_cmnd *) cp->scsi_cmd; - ctlr = hba[cp->ctlr]; + cmd = (struct scsi_cmnd *) c->scsi_cmd; + h = hba[c->ctlr]; scsi_dma_unmap(cmd); - if (cp->Header.SGTotal > ctlr->max_cmd_sgentries) - cciss_unmap_sg_chain_block(ctlr, cp); + if (c->Header.SGTotal > h->max_cmd_sgentries) + cciss_unmap_sg_chain_block(h, c); cmd->result = (DID_OK << 16); /* host byte */ cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */ @@ -764,9 +765,8 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) { #if 0 printk(KERN_WARNING "cciss: cmd %p " - "has SCSI Status = %x\n", - cp, - ei->ScsiStatus); + "has SCSI Status = %x\n", + c, ei->ScsiStatus); #endif cmd->result |= (ei->ScsiStatus << 1); } @@ -786,13 +786,13 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ break; case CMD_DATA_OVERRUN: - printk(KERN_WARNING "cciss: cp %p has" + printk(KERN_WARNING "cciss: %p has" " completed with data overrun " - "reported\n", cp); + "reported\n", c); break; case CMD_INVALID: { - /* print_bytes(cp, sizeof(*cp), 1, 0); - print_cmd(cp); */ + /* print_bytes(c, sizeof(*c), 1, 0); + print_cmd(c); */ /* We get CMD_INVALID if you address a non-existent tape drive instead of a selection timeout (no response). You will see this if you yank out a tape drive, then try to access it. This is kind of a shame @@ -802,54 +802,52 @@ complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag) } break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cp %p has " - "protocol error \n", cp); + printk(KERN_WARNING "cciss: %p has " + "protocol error\n", c); break; case CMD_HARDWARE_ERR: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: cp %p had " - " hardware error\n", cp); + printk(KERN_WARNING "cciss: %p had " + " hardware error\n", c); break; case CMD_CONNECTION_LOST: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: cp %p had " - "connection lost\n", cp); + printk(KERN_WARNING "cciss: %p had " + "connection lost\n", c); break; case CMD_ABORTED: cmd->result = DID_ABORT << 16; - printk(KERN_WARNING "cciss: cp %p was " - "aborted\n", cp); + printk(KERN_WARNING "cciss: %p was " + "aborted\n", c); break; case CMD_ABORT_FAILED: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: cp %p reports " - "abort failed\n", cp); + printk(KERN_WARNING "cciss: %p reports " + "abort failed\n", c); break; case CMD_UNSOLICITED_ABORT: cmd->result = DID_ABORT << 16; - printk(KERN_WARNING "cciss: cp %p aborted " - "do to an unsolicited abort\n", cp); + printk(KERN_WARNING "cciss: %p aborted " + "do to an unsolicited abort\n", c); break; case CMD_TIMEOUT: cmd->result = DID_TIME_OUT << 16; - printk(KERN_WARNING "cciss: cp %p timedout\n", - cp); + printk(KERN_WARNING "cciss: %p timedout\n", + c); break; default: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: cp %p returned " - "unknown status %x\n", cp, + printk(KERN_WARNING "cciss: %p returned " + "unknown status %x\n", c, ei->CommandStatus); } } - // printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel, - // cmd->target, cmd->lun); cmd->scsi_done(cmd); - scsi_cmd_free(ctlr, cp); + scsi_cmd_free(h, c); } static int -cciss_scsi_detect(int ctlr) +cciss_scsi_detect(ctlr_info_t *h) { struct Scsi_Host *sh; int error; @@ -860,15 +858,15 @@ cciss_scsi_detect(int ctlr) sh->io_port = 0; // good enough? FIXME, sh->n_io_port = 0; // I don't think we use these two... sh->this_id = SELF_SCSI_ID; - sh->sg_tablesize = hba[ctlr]->maxsgentries; + sh->sg_tablesize = h->maxsgentries; sh->max_cmd_len = MAX_COMMAND_SIZE; ((struct cciss_scsi_adapter_data_t *) - hba[ctlr]->scsi_ctlr)->scsi_host = sh; - sh->hostdata[0] = (unsigned long) hba[ctlr]; - sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT]; + h->scsi_ctlr)->scsi_host = sh; + sh->hostdata[0] = (unsigned long) h; + sh->irq = h->intr[SIMPLE_MODE_INT]; sh->unique_id = sh->irq; - error = scsi_add_host(sh, &hba[ctlr]->pdev->dev); + error = scsi_add_host(sh, &h->pdev->dev); if (error) goto fail_host_put; scsi_scan_host(sh); @@ -882,20 +880,20 @@ cciss_scsi_detect(int ctlr) static void cciss_unmap_one(struct pci_dev *pdev, - CommandList_struct *cp, + CommandList_struct *c, size_t buflen, int data_direction) { u64bit addr64; - addr64.val32.lower = cp->SG[0].Addr.lower; - addr64.val32.upper = cp->SG[0].Addr.upper; + addr64.val32.lower = c->SG[0].Addr.lower; + addr64.val32.upper = c->SG[0].Addr.upper; pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction); } static void cciss_map_one(struct pci_dev *pdev, - CommandList_struct *cp, + CommandList_struct *c, unsigned char *buf, size_t buflen, int data_direction) @@ -903,18 +901,18 @@ cciss_map_one(struct pci_dev *pdev, __u64 addr64; addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction); - cp->SG[0].Addr.lower = + c->SG[0].Addr.lower = (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF); - cp->SG[0].Addr.upper = + c->SG[0].Addr.upper = (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF); - cp->SG[0].Len = buflen; - cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ - cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ + c->SG[0].Len = buflen; + c->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */ + c->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */ } static int -cciss_scsi_do_simple_cmd(ctlr_info_t *c, - CommandList_struct *cp, +cciss_scsi_do_simple_cmd(ctlr_info_t *h, + CommandList_struct *c, unsigned char *scsi3addr, unsigned char *cdb, unsigned char cdblen, @@ -923,53 +921,52 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *c, { DECLARE_COMPLETION_ONSTACK(wait); - cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl - cp->scsi_cmd = NULL; - cp->Header.ReplyQueue = 0; // unused in simple mode - memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN)); - cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag + c->cmd_type = CMD_IOCTL_PEND; /* treat this like an ioctl */ + c->scsi_cmd = NULL; + c->Header.ReplyQueue = 0; /* unused in simple mode */ + memcpy(&c->Header.LUN, scsi3addr, sizeof(c->Header.LUN)); + c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ // Fill in the request block... /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n", scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3], scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */ - memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); - memcpy(cp->Request.CDB, cdb, cdblen); - cp->Request.Timeout = 0; - cp->Request.CDBLen = cdblen; - cp->Request.Type.Type = TYPE_CMD; - cp->Request.Type.Attribute = ATTR_SIMPLE; - cp->Request.Type.Direction = direction; + memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); + memcpy(c->Request.CDB, cdb, cdblen); + c->Request.Timeout = 0; + c->Request.CDBLen = cdblen; + c->Request.Type.Type = TYPE_CMD; + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = direction; /* Fill in the SG list and do dma mapping */ - cciss_map_one(c->pdev, cp, (unsigned char *) buf, + cciss_map_one(h->pdev, c, (unsigned char *) buf, bufsize, DMA_FROM_DEVICE); - cp->waiting = &wait; - enqueue_cmd_and_start_io(c, cp); + c->waiting = &wait; + enqueue_cmd_and_start_io(h, c); wait_for_completion(&wait); /* undo the dma mapping */ - cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE); + cciss_unmap_one(h->pdev, c, bufsize, DMA_FROM_DEVICE); return(0); } static void -cciss_scsi_interpret_error(CommandList_struct *cp) +cciss_scsi_interpret_error(CommandList_struct *c) { ErrorInfo_struct *ei; - ei = cp->err_info; + ei = c->err_info; switch(ei->CommandStatus) { case CMD_TARGET_STATUS: printk(KERN_WARNING "cciss: cmd %p has " - "completed with errors\n", cp); + "completed with errors\n", c); printk(KERN_WARNING "cciss: cmd %p " "has SCSI Status = %x\n", - cp, - ei->ScsiStatus); + c, ei->ScsiStatus); if (ei->ScsiStatus == 0) printk(KERN_WARNING "cciss:SCSI status is abnormally zero. " @@ -981,78 +978,75 @@ cciss_scsi_interpret_error(CommandList_struct *cp) printk("UNDERRUN\n"); break; case CMD_DATA_OVERRUN: - printk(KERN_WARNING "cciss: cp %p has" + printk(KERN_WARNING "cciss: %p has" " completed with data overrun " - "reported\n", cp); + "reported\n", c); break; case CMD_INVALID: { /* controller unfortunately reports SCSI passthru's */ /* to non-existent targets as invalid commands. */ - printk(KERN_WARNING "cciss: cp %p is " + printk(KERN_WARNING "cciss: %p is " "reported invalid (probably means " - "target device no longer present)\n", - cp); - /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0); - print_cmd(cp); */ + "target device no longer present)\n", c); + /* print_bytes((unsigned char *) c, sizeof(*c), 1, 0); + print_cmd(c); */ } break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cp %p has " - "protocol error \n", cp); + printk(KERN_WARNING "cciss: %p has " + "protocol error\n", c); break; case CMD_HARDWARE_ERR: /* cmd->result = DID_ERROR << 16; */ - printk(KERN_WARNING "cciss: cp %p had " - " hardware error\n", cp); + printk(KERN_WARNING "cciss: %p had " + " hardware error\n", c); break; case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cp %p had " - "connection lost\n", cp); + printk(KERN_WARNING "cciss: %p had " + "connection lost\n", c); break; case CMD_ABORTED: - printk(KERN_WARNING "cciss: cp %p was " - "aborted\n", cp); + printk(KERN_WARNING "cciss: %p was " + "aborted\n", c); break; case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cp %p reports " - "abort failed\n", cp); + printk(KERN_WARNING "cciss: %p reports " + "abort failed\n", c); break; case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING "cciss: cp %p aborted " - "do to an unsolicited abort\n", cp); + printk(KERN_WARNING "cciss: %p aborted " + "do to an unsolicited abort\n", c); break; case CMD_TIMEOUT: - printk(KERN_WARNING "cciss: cp %p timedout\n", - cp); + printk(KERN_WARNING "cciss: %p timedout\n", c); break; default: - printk(KERN_WARNING "cciss: cp %p returned " - "unknown status %x\n", cp, - ei->CommandStatus); + printk(KERN_WARNING "cciss: %p returned " + "unknown status %x\n", c, ei->CommandStatus); } } static int -cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, +cciss_scsi_do_inquiry(ctlr_info_t *h, unsigned char *scsi3addr, unsigned char page, unsigned char *buf, unsigned char bufsize) { int rc; - CommandList_struct *cp; + CommandList_struct *c; char cdb[6]; ErrorInfo_struct *ei; unsigned long flags; - spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); - cp = scsi_cmd_alloc(c); - spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); + c = scsi_cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); - if (cp == NULL) { /* trouble... */ + if (c == NULL) { /* trouble... */ printk("cmd_alloc returned NULL!\n"); return -1; } - ei = cp->err_info; + ei = c->err_info; cdb[0] = CISS_INQUIRY; cdb[1] = (page != 0); @@ -1060,24 +1054,24 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, cdb[3] = 0; cdb[4] = bufsize; cdb[5] = 0; - rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb, + rc = cciss_scsi_do_simple_cmd(h, c, scsi3addr, cdb, 6, buf, bufsize, XFER_READ); if (rc != 0) return rc; /* something went wrong */ if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { - cciss_scsi_interpret_error(cp); + cciss_scsi_interpret_error(c); rc = -1; } - spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); - scsi_cmd_free(c, cp); - spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); + scsi_cmd_free(h, c); + spin_unlock_irqrestore(&h->lock, flags); return rc; } /* Get the device id from inquiry page 0x83 */ -static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, +static int cciss_scsi_get_device_id(ctlr_info_t *h, unsigned char *scsi3addr, unsigned char *device_id, int buflen) { int rc; @@ -1088,7 +1082,7 @@ static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, buf = kzalloc(64, GFP_KERNEL); if (!buf) return -1; - rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64); + rc = cciss_scsi_do_inquiry(h, scsi3addr, 0x83, buf, 64); if (rc == 0) memcpy(device_id, &buf[8], buflen); kfree(buf); @@ -1096,20 +1090,20 @@ static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, } static int -cciss_scsi_do_report_phys_luns(ctlr_info_t *c, +cciss_scsi_do_report_phys_luns(ctlr_info_t *h, ReportLunData_struct *buf, int bufsize) { int rc; - CommandList_struct *cp; + CommandList_struct *c; unsigned char cdb[12]; unsigned char scsi3addr[8]; ErrorInfo_struct *ei; unsigned long flags; - spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); - cp = scsi_cmd_alloc(c); - spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); - if (cp == NULL) { /* trouble... */ + spin_lock_irqsave(&h->lock, flags); + c = scsi_cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); + if (c == NULL) { /* trouble... */ printk("cmd_alloc returned NULL!\n"); return -1; } @@ -1128,27 +1122,27 @@ cciss_scsi_do_report_phys_luns(ctlr_info_t *c, cdb[10] = 0; cdb[11] = 0; - rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, + rc = cciss_scsi_do_simple_cmd(h, c, scsi3addr, cdb, 12, (unsigned char *) buf, bufsize, XFER_READ); if (rc != 0) return rc; /* something went wrong */ - ei = cp->err_info; + ei = c->err_info; if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { - cciss_scsi_interpret_error(cp); + cciss_scsi_interpret_error(c); rc = -1; } - spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags); - scsi_cmd_free(c, cp); - spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags); + spin_lock_irqsave(&h->lock, flags); + scsi_cmd_free(h, c); + spin_unlock_irqrestore(&h->lock, flags); return rc; } static void -cciss_update_non_disk_devices(int cntl_num, int hostno) +cciss_update_non_disk_devices(ctlr_info_t *h, int hostno) { /* the idea here is we could get notified from /proc that some devices have changed, so we do a report @@ -1181,7 +1175,6 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) ReportLunData_struct *ld_buff; unsigned char *inq_buff; unsigned char scsi3addr[8]; - ctlr_info_t *c; __u32 num_luns=0; unsigned char *ch; struct cciss_scsi_dev_t *currentsd, *this_device; @@ -1189,7 +1182,6 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8; int i; - c = (ctlr_info_t *) hba[cntl_num]; ld_buff = kzalloc(reportlunsize, GFP_KERNEL); inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); currentsd = kzalloc(sizeof(*currentsd) * @@ -1199,7 +1191,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) goto out; } this_device = ¤tsd[CCISS_MAX_SCSI_DEVS_PER_HBA]; - if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) { + if (cciss_scsi_do_report_phys_luns(h, ld_buff, reportlunsize) == 0) { ch = &ld_buff->LUNListLength[0]; num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8; if (num_luns > CISS_MAX_PHYS_LUN) { @@ -1223,7 +1215,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); - if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff, + if (cciss_scsi_do_inquiry(h, scsi3addr, 0, inq_buff, (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) /* Inquiry failed (msg printed already) */ continue; /* so we will skip this device. */ @@ -1241,7 +1233,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) sizeof(this_device->revision)); memset(this_device->device_id, 0, sizeof(this_device->device_id)); - cciss_scsi_get_device_id(hba[cntl_num], scsi3addr, + cciss_scsi_get_device_id(h, scsi3addr, this_device->device_id, sizeof(this_device->device_id)); switch (this_device->devtype) @@ -1268,7 +1260,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) case 0x08: /* medium changer */ if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { printk(KERN_INFO "cciss%d: %s ignored, " - "too many devices.\n", cntl_num, + "too many devices.\n", h->ctlr, scsi_device_type(this_device->devtype)); break; } @@ -1280,7 +1272,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) } } - adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent); + adjust_cciss_scsi_table(h, hostno, currentsd, ncurrent); out: kfree(inq_buff); kfree(ld_buff); @@ -1299,12 +1291,12 @@ is_keyword(char *ptr, int len, char *verb) // Thanks to ncr53c8xx.c } static int -cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length) +cciss_scsi_user_command(ctlr_info_t *h, int hostno, char *buffer, int length) { int arg_len; if ((arg_len = is_keyword(buffer, length, "rescan")) != 0) - cciss_update_non_disk_devices(ctlr, hostno); + cciss_update_non_disk_devices(h, hostno); else return -EINVAL; return length; @@ -1321,20 +1313,16 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, { int buflen, datalen; - ctlr_info_t *ci; + ctlr_info_t *h; int i; - int cntl_num; - - ci = (ctlr_info_t *) sh->hostdata[0]; - if (ci == NULL) /* This really shouldn't ever happen. */ + h = (ctlr_info_t *) sh->hostdata[0]; + if (h == NULL) /* This really shouldn't ever happen. */ return -EINVAL; - cntl_num = ci->ctlr; /* Get our index into the hba[] array */ - if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */ buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n", - cntl_num, sh->host_no); + h->ctlr, sh->host_no); /* this information is needed by apps to know which cciss device corresponds to which scsi host number without @@ -1344,8 +1332,9 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, this info is for an app to be able to use to know how to get them back in sync. */ - for (i=0;ictlr].ndevices; i++) { + struct cciss_scsi_dev_t *sd = + &ccissscsi[h->ctlr].dev[i]; buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d " "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", sh->host_no, sd->bus, sd->target, sd->lun, @@ -1363,15 +1352,15 @@ cciss_scsi_proc_info(struct Scsi_Host *sh, *start = buffer + offset; return(datalen); } else /* User is writing to /proc/scsi/cciss*?/?* ... */ - return cciss_scsi_user_command(cntl_num, sh->host_no, + return cciss_scsi_user_command(h, sh->host_no, buffer, length); } /* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci dma mapping and fills in the scatter gather entries of the - cciss command, cp. */ + cciss command, c. */ -static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, +static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *c, struct scsi_cmnd *cmd) { unsigned int len; @@ -1385,7 +1374,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, chained = 0; sg_index = 0; - curr_sg = cp->SG; + curr_sg = c->SG; request_nsgs = scsi_dma_map(cmd); if (request_nsgs) { scsi_for_each_sg(cmd, sg, request_nsgs, i) { @@ -1393,7 +1382,7 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, !chained && request_nsgs - i > 1) { chained = 1; sg_index = 0; - curr_sg = sa->cmd_sg_list[cp->cmdindex]; + curr_sg = sa->cmd_sg_list[c->cmdindex]; } addr64 = (__u64) sg_dma_address(sg); len = sg_dma_len(sg); @@ -1406,19 +1395,19 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, ++sg_index; } if (chained) - cciss_map_sg_chain_block(h, cp, - sa->cmd_sg_list[cp->cmdindex], + cciss_map_sg_chain_block(h, c, + sa->cmd_sg_list[c->cmdindex], (request_nsgs - (h->max_cmd_sgentries - 1)) * sizeof(SGDescriptor_struct)); } /* track how many SG entries we are using */ if (request_nsgs > h->maxSG) h->maxSG = request_nsgs; - cp->Header.SGTotal = (__u8) request_nsgs + chained; + c->Header.SGTotal = (__u8) request_nsgs + chained; if (request_nsgs > h->max_cmd_sgentries) - cp->Header.SGList = h->max_cmd_sgentries; + c->Header.SGList = h->max_cmd_sgentries; else - cp->Header.SGList = cp->Header.SGTotal; + c->Header.SGList = c->Header.SGTotal; return; } @@ -1426,18 +1415,17 @@ static void cciss_scatter_gather(ctlr_info_t *h, CommandList_struct *cp, static int cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *)) { - ctlr_info_t *c; - int ctlr, rc; + ctlr_info_t *h; + int rc; unsigned char scsi3addr[8]; - CommandList_struct *cp; + CommandList_struct *c; unsigned long flags; // Get the ptr to our adapter structure (hba[i]) out of cmd->host. // We violate cmd->host privacy here. (Is there another way?) - c = (ctlr_info_t *) cmd->device->host->hostdata[0]; - ctlr = c->ctlr; + h = (ctlr_info_t *) cmd->device->host->hostdata[0]; - rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id, + rc = lookup_scsi3addr(h, cmd->device->channel, cmd->device->id, cmd->device->lun, scsi3addr); if (rc != 0) { /* the scsi nexus does not match any that we presented... */ @@ -1449,18 +1437,13 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd return 0; } - /* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n", - cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/ - // printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel, - // cmd->target, cmd->lun); - /* Ok, we have a reasonable scsi nexus, so send the cmd down, and see what the device thinks of it. */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - cp = scsi_cmd_alloc(c); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - if (cp == NULL) { /* trouble... */ + spin_lock_irqsave(&h->lock, flags); + c = scsi_cmd_alloc(h); + spin_unlock_irqrestore(&h->lock, flags); + if (c == NULL) { /* trouble... */ printk("scsi_cmd_alloc returned NULL!\n"); /* FIXME: next 3 lines are -> BAD! <- */ cmd->result = DID_NO_CONNECT << 16; @@ -1472,35 +1455,41 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd cmd->scsi_done = done; // save this for use by completion code - // save cp in case we have to abort it - cmd->host_scribble = (unsigned char *) cp; + /* save c in case we have to abort it */ + cmd->host_scribble = (unsigned char *) c; - cp->cmd_type = CMD_SCSI; - cp->scsi_cmd = cmd; - cp->Header.ReplyQueue = 0; // unused in simple mode - memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); - cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag + c->cmd_type = CMD_SCSI; + c->scsi_cmd = cmd; + c->Header.ReplyQueue = 0; /* unused in simple mode */ + memcpy(&c->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8); + c->Header.Tag.lower = c->busaddr; /* Use k. address of cmd as tag */ // Fill in the request block... - cp->Request.Timeout = 0; - memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB)); - BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB)); - cp->Request.CDBLen = cmd->cmd_len; - memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len); - cp->Request.Type.Type = TYPE_CMD; - cp->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Timeout = 0; + memset(c->Request.CDB, 0, sizeof(c->Request.CDB)); + BUG_ON(cmd->cmd_len > sizeof(c->Request.CDB)); + c->Request.CDBLen = cmd->cmd_len; + memcpy(c->Request.CDB, cmd->cmnd, cmd->cmd_len); + c->Request.Type.Type = TYPE_CMD; + c->Request.Type.Attribute = ATTR_SIMPLE; switch(cmd->sc_data_direction) { - case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break; - case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break; - case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break; + case DMA_TO_DEVICE: + c->Request.Type.Direction = XFER_WRITE; + break; + case DMA_FROM_DEVICE: + c->Request.Type.Direction = XFER_READ; + break; + case DMA_NONE: + c->Request.Type.Direction = XFER_NONE; + break; case DMA_BIDIRECTIONAL: // This can happen if a buggy application does a scsi passthru // and sets both inlen and outlen to non-zero. ( see // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() ) - cp->Request.Type.Direction = XFER_RSVD; + c->Request.Type.Direction = XFER_RSVD; // This is technically wrong, and cciss controllers should // reject it with CMD_INVALID, which is the most correct // response, but non-fibre backends appear to let it @@ -1516,14 +1505,13 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd BUG(); break; } - cciss_scatter_gather(c, cp, cmd); - enqueue_cmd_and_start_io(c, cp); + cciss_scatter_gather(h, c, cmd); + enqueue_cmd_and_start_io(h, c); /* the cmd'll come back via intr handler in complete_scsi_command() */ return 0; } -static void -cciss_unregister_scsi(int ctlr) +static void cciss_unregister_scsi(ctlr_info_t *h) { struct cciss_scsi_adapter_data_t *sa; struct cciss_scsi_cmd_stack_t *stk; @@ -1531,59 +1519,59 @@ cciss_unregister_scsi(int ctlr) /* we are being forcibly unloaded, and may not refuse. */ - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - sa = hba[ctlr]->scsi_ctlr; + spin_lock_irqsave(&h->lock, flags); + sa = h->scsi_ctlr; stk = &sa->cmd_stack; /* if we weren't ever actually registered, don't unregister */ if (sa->registered) { - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + spin_unlock_irqrestore(&h->lock, flags); scsi_remove_host(sa->scsi_host); scsi_host_put(sa->scsi_host); - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); + spin_lock_irqsave(&h->lock, flags); } /* set scsi_host to NULL so our detect routine will find us on register */ sa->scsi_host = NULL; - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - scsi_cmd_stack_free(ctlr); + spin_unlock_irqrestore(&h->lock, flags); + scsi_cmd_stack_free(h); kfree(sa); } -static int -cciss_engage_scsi(int ctlr) +static int cciss_engage_scsi(ctlr_info_t *h) { struct cciss_scsi_adapter_data_t *sa; struct cciss_scsi_cmd_stack_t *stk; unsigned long flags; - spin_lock_irqsave(CCISS_LOCK(ctlr), flags); - sa = hba[ctlr]->scsi_ctlr; + spin_lock_irqsave(&h->lock, flags); + sa = h->scsi_ctlr; stk = &sa->cmd_stack; if (sa->registered) { - printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); + printk(KERN_INFO "cciss%d: SCSI subsystem already engaged.\n", + h->ctlr); + spin_unlock_irqrestore(&h->lock, flags); return -ENXIO; } sa->registered = 1; - spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); - cciss_update_non_disk_devices(ctlr, -1); - cciss_scsi_detect(ctlr); + spin_unlock_irqrestore(&h->lock, flags); + cciss_update_non_disk_devices(h, -1); + cciss_scsi_detect(h); return 0; } static void -cciss_seq_tape_report(struct seq_file *seq, int ctlr) +cciss_seq_tape_report(struct seq_file *seq, ctlr_info_t *h) { unsigned long flags; - CPQ_TAPE_LOCK(ctlr, flags); + CPQ_TAPE_LOCK(h, flags); seq_printf(seq, "Sequential access devices: %d\n\n", - ccissscsi[ctlr].ndevices); - CPQ_TAPE_UNLOCK(ctlr, flags); + ccissscsi[h->ctlr].ndevices); + CPQ_TAPE_UNLOCK(h, flags); } static int wait_for_device_to_become_ready(ctlr_info_t *h, @@ -1615,7 +1603,7 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, waittime = waittime * 2; /* Send the Test Unit Ready */ - rc = fill_cmd(c, TEST_UNIT_READY, h->ctlr, NULL, 0, 0, + rc = fill_cmd(h, c, TEST_UNIT_READY, NULL, 0, 0, lunaddr, TYPE_CMD); if (rc == 0) rc = sendcmd_withirq_core(h, c, 0); @@ -1672,26 +1660,25 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) int rc; CommandList_struct *cmd_in_trouble; unsigned char lunaddr[8]; - ctlr_info_t *c; - int ctlr; + ctlr_info_t *h; /* find the controller to which the command to be aborted was sent */ - c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; - if (c == NULL) /* paranoia */ + h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; + if (h == NULL) /* paranoia */ return FAILED; - ctlr = c->ctlr; - printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr); + printk(KERN_WARNING + "cciss%d: resetting tape drive or medium changer.\n", h->ctlr); /* find the command that's giving us trouble */ cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble; if (cmd_in_trouble == NULL) /* paranoia */ return FAILED; memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8); /* send a reset to the SCSI LUN which the command was sent to */ - rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr, + rc = sendcmd_withirq(h, CCISS_RESET_MSG, NULL, 0, 0, lunaddr, TYPE_MSG); - if (rc == 0 && wait_for_device_to_become_ready(c, lunaddr) == 0) + if (rc == 0 && wait_for_device_to_become_ready(h, lunaddr) == 0) return SUCCESS; - printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr); + printk(KERN_WARNING "cciss%d: resetting device failed.\n", h->ctlr); return FAILED; } @@ -1700,22 +1687,20 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) int rc; CommandList_struct *cmd_to_abort; unsigned char lunaddr[8]; - ctlr_info_t *c; - int ctlr; + ctlr_info_t *h; /* find the controller to which the command to be aborted was sent */ - c = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; - if (c == NULL) /* paranoia */ + h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; + if (h == NULL) /* paranoia */ return FAILED; - ctlr = c->ctlr; - printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr); + printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", h->ctlr); /* find the command to be aborted */ cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble; if (cmd_to_abort == NULL) /* paranoia */ return FAILED; memcpy(lunaddr, &cmd_to_abort->Header.LUN.LunAddrBytes[0], 8); - rc = sendcmd_withirq(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag, + rc = sendcmd_withirq(h, CCISS_ABORT_MSG, &cmd_to_abort->Header.Tag, 0, 0, lunaddr, TYPE_MSG); if (rc == 0) return SUCCESS; -- cgit v1.2.3-70-g09d2 From 6b4d96b878d67c6768766e682c188a2a8bdc804a Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:43 -0500 Subject: cciss: separate cmd_alloc() and cmd_special_alloc() cciss: separate cmd_alloc() and cmd_special_alloc() cmd_alloc() took a parameter which caused it to either allocate from a pre-allocated pool, or allocate using pci_alloc_consistent. This parameter is always known at compile time, so this would be better handled by breaking the function into two functions and differentiating the cases by function names. Same goes for cmd_free(). Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 153 ++++++++++++++++++++++++--------------------- drivers/block/cciss_scsi.c | 10 +-- 2 files changed, 89 insertions(+), 74 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 70ad24f3604..1dc95740b3b 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -907,60 +907,73 @@ static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index, /* * For operations that cannot sleep, a command block is allocated at init, * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track - * which ones are free or in use. For operations that can wait for kmalloc - * to possible sleep, this routine can be called with get_from_pool set to 0. - * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was. + * which ones are free or in use. */ -static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) +static CommandList_struct *cmd_alloc(ctlr_info_t *h) { CommandList_struct *c; int i; u64bit temp64; dma_addr_t cmd_dma_handle, err_dma_handle; - if (!get_from_pool) { - c = (CommandList_struct *) pci_alloc_consistent(h->pdev, - sizeof(CommandList_struct), &cmd_dma_handle); - if (c == NULL) + do { + i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); + if (i == h->nr_cmds) return NULL; - memset(c, 0, sizeof(CommandList_struct)); + } while (test_and_set_bit(i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); +#ifdef CCISS_DEBUG + printk(KERN_DEBUG "cciss: using command buffer %d\n", i); +#endif + c = h->cmd_pool + i; + memset(c, 0, sizeof(CommandList_struct)); + cmd_dma_handle = h->cmd_pool_dhandle + i * sizeof(CommandList_struct); + c->err_info = h->errinfo_pool + i; + memset(c->err_info, 0, sizeof(ErrorInfo_struct)); + err_dma_handle = h->errinfo_pool_dhandle + + i * sizeof(ErrorInfo_struct); + h->nr_allocs++; - c->cmdindex = -1; + c->cmdindex = i; - c->err_info = (ErrorInfo_struct *) - pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), - &err_dma_handle); + INIT_HLIST_NODE(&c->list); + c->busaddr = (__u32) cmd_dma_handle; + temp64.val = (__u64) err_dma_handle; + c->ErrDesc.Addr.lower = temp64.val32.lower; + c->ErrDesc.Addr.upper = temp64.val32.upper; + c->ErrDesc.Len = sizeof(ErrorInfo_struct); - if (c->err_info == NULL) { - pci_free_consistent(h->pdev, - sizeof(CommandList_struct), c, cmd_dma_handle); - return NULL; - } - memset(c->err_info, 0, sizeof(ErrorInfo_struct)); - } else { /* get it out of the controllers pool */ - - do { - i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); - if (i == h->nr_cmds) - return NULL; - } while (test_and_set_bit - (i & (BITS_PER_LONG - 1), - h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss: using command buffer %d\n", i); -#endif - c = h->cmd_pool + i; - memset(c, 0, sizeof(CommandList_struct)); - cmd_dma_handle = h->cmd_pool_dhandle - + i * sizeof(CommandList_struct); - c->err_info = h->errinfo_pool + i; - memset(c->err_info, 0, sizeof(ErrorInfo_struct)); - err_dma_handle = h->errinfo_pool_dhandle - + i * sizeof(ErrorInfo_struct); - h->nr_allocs++; + c->ctlr = h->ctlr; + return c; +} + +/* allocate a command using pci_alloc_consistent, used for ioctls, + * etc., not for the main i/o path. + */ +static CommandList_struct *cmd_special_alloc(ctlr_info_t *h) +{ + CommandList_struct *c; + u64bit temp64; + dma_addr_t cmd_dma_handle, err_dma_handle; + + c = (CommandList_struct *) pci_alloc_consistent(h->pdev, + sizeof(CommandList_struct), &cmd_dma_handle); + if (c == NULL) + return NULL; + memset(c, 0, sizeof(CommandList_struct)); + + c->cmdindex = -1; + + c->err_info = (ErrorInfo_struct *) + pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), + &err_dma_handle); - c->cmdindex = i; + if (c->err_info == NULL) { + pci_free_consistent(h->pdev, + sizeof(CommandList_struct), c, cmd_dma_handle); + return NULL; } + memset(c->err_info, 0, sizeof(ErrorInfo_struct)); INIT_HLIST_NODE(&c->list); c->busaddr = (__u32) cmd_dma_handle; @@ -973,27 +986,26 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) return c; } -/* - * Frees a command block that was previously allocated with cmd_alloc(). - */ -static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool) +static void cmd_free(ctlr_info_t *h, CommandList_struct *c) { int i; + + i = c - h->cmd_pool; + clear_bit(i & (BITS_PER_LONG - 1), + h->cmd_pool_bits + (i / BITS_PER_LONG)); + h->nr_frees++; +} + +static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c) +{ u64bit temp64; - if (!got_from_pool) { - temp64.val32.lower = c->ErrDesc.Addr.lower; - temp64.val32.upper = c->ErrDesc.Addr.upper; - pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), - c->err_info, (dma_addr_t) temp64.val); - pci_free_consistent(h->pdev, sizeof(CommandList_struct), - c, (dma_addr_t) c->busaddr); - } else { - i = c - h->cmd_pool; - clear_bit(i & (BITS_PER_LONG - 1), - h->cmd_pool_bits + (i / BITS_PER_LONG)); - h->nr_frees++; - } + temp64.val32.lower = c->ErrDesc.Addr.lower; + temp64.val32.upper = c->ErrDesc.Addr.upper; + pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), + c->err_info, (dma_addr_t) temp64.val); + pci_free_consistent(h->pdev, sizeof(CommandList_struct), + c, (dma_addr_t) c->busaddr); } static inline ctlr_info_t *get_host(struct gendisk *disk) @@ -1470,7 +1482,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, } else { memset(buff, 0, iocommand.buf_size); } - c = cmd_alloc(h, 0); + c = cmd_special_alloc(h); if (!c) { kfree(buff); return -ENOMEM; @@ -1524,7 +1536,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (copy_to_user (argp, &iocommand, sizeof(IOCTL_Command_struct))) { kfree(buff); - cmd_free(h, c, 0); + cmd_special_free(h, c); return -EFAULT; } @@ -1533,12 +1545,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, if (copy_to_user (iocommand.buf, buff, iocommand.buf_size)) { kfree(buff); - cmd_free(h, c, 0); + cmd_special_free(h, c); return -EFAULT; } } kfree(buff); - cmd_free(h, c, 0); + cmd_special_free(h, c); return 0; } case CCISS_BIG_PASSTHRU:{ @@ -1620,7 +1632,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, data_ptr += sz; sg_used++; } - c = cmd_alloc(h, 0); + c = cmd_special_alloc(h); if (!c) { status = -ENOMEM; goto cleanup1; @@ -1668,7 +1680,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, /* Copy the error information out */ ioc->error_info = *(c->err_info); if (copy_to_user(argp, ioc, sizeof(*ioc))) { - cmd_free(h, c, 0); + cmd_special_free(h, c); status = -EFAULT; goto cleanup1; } @@ -1678,14 +1690,14 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, for (i = 0; i < sg_used; i++) { if (copy_to_user (ptr, buff[i], buff_size[i])) { - cmd_free(h, c, 0); + cmd_special_free(h, c); status = -EFAULT; goto cleanup1; } ptr += buff_size[i]; } } - cmd_free(h, c, 0); + cmd_special_free(h, c); status = 0; cleanup1: if (buff) { @@ -1813,7 +1825,7 @@ static void cciss_softirq_done(struct request *rq) blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); spin_lock_irqsave(&h->lock, flags); - cmd_free(h, c, 1); + cmd_free(h, c); cciss_check_queues(h); spin_unlock_irqrestore(&h->lock, flags); } @@ -2765,7 +2777,7 @@ static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, CommandList_struct *c; int return_status; - c = cmd_alloc(h, 0); + c = cmd_special_alloc(h); if (!c) return -ENOMEM; return_status = fill_cmd(h, c, cmd, buff, size, page_code, @@ -2773,7 +2785,7 @@ static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size, if (return_status == IO_OK) return_status = sendcmd_withirq_core(h, c, 1); - cmd_free(h, c, 0); + cmd_special_free(h, c); return return_status; } @@ -3240,7 +3252,8 @@ static void do_cciss_request(struct request_queue *q) BUG_ON(creq->nr_phys_segments > h->maxsgentries); - if ((c = cmd_alloc(h, 1)) == NULL) + c = cmd_alloc(h); + if (!c) goto full; blk_start_request(creq); diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 9133ad4c7b1..9fe0d8ffc90 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -49,8 +49,10 @@ static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, __u8 page_code, unsigned char *scsi3addr, int cmd_type); -static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool); -static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool); +static CommandList_struct *cmd_alloc(ctlr_info_t *h); +static CommandList_struct *cmd_special_alloc(ctlr_info_t *h); +static void cmd_free(ctlr_info_t *h, CommandList_struct *c); +static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c); static int cciss_scsi_proc_info( struct Scsi_Host *sh, @@ -1582,7 +1584,7 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, int waittime = HZ; CommandList_struct *c; - c = cmd_alloc(h, 1); + c = cmd_alloc(h); if (!c) { printk(KERN_WARNING "cciss%d: out of memory in " "wait_for_device_to_become_ready.\n", h->ctlr); @@ -1640,7 +1642,7 @@ retry_tur: else printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr); - cmd_free(h, c, 1); + cmd_free(h, c); return rc; } -- cgit v1.2.3-70-g09d2 From b2a4a43dbaf10383703d512bbe560d5a24da0bf2 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:48 -0500 Subject: cciss: change printks to dev_warn, etc. cciss: change printks to dev_warn, etc. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 314 ++++++++++++++++++++------------------------- drivers/block/cciss_scsi.c | 159 +++++++++++------------ 2 files changed, 212 insertions(+), 261 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1dc95740b3b..35a9f08cf74 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -922,9 +922,6 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h) return NULL; } while (test_and_set_bit(i & (BITS_PER_LONG - 1), h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss: using command buffer %d\n", i); -#endif c = h->cmd_pool + i; memset(c, 0, sizeof(CommandList_struct)); cmd_dma_handle = h->cmd_pool_dhandle + i * sizeof(CommandList_struct); @@ -1026,10 +1023,7 @@ static int cciss_open(struct block_device *bdev, fmode_t mode) ctlr_info_t *h = get_host(bdev->bd_disk); drive_info_struct *drv = get_drv(bdev->bd_disk); -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_open %s\n", bdev->bd_disk->disk_name); -#endif /* CCISS_DEBUG */ - + dev_dbg(&h->pdev->dev, "cciss_open %s\n", bdev->bd_disk->disk_name); if (drv->busy_configuring) return -EBUSY; /* @@ -1081,11 +1075,7 @@ static int cciss_release(struct gendisk *disk, fmode_t mode) lock_kernel(); h = get_host(disk); drv = get_drv(disk); - -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_release %s\n", disk->disk_name); -#endif /* CCISS_DEBUG */ - + dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name); drv->usage_count--; h->usage_count--; unlock_kernel(); @@ -1251,10 +1241,8 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, drive_info_struct *drv = get_drv(disk); void __user *argp = (void __user *)arg; -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss_ioctl: Called with cmd=%x %lx\n", cmd, arg); -#endif /* CCISS_DEBUG */ - + dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n", + cmd, arg); switch (cmd) { case CCISS_GETPCIINFO: { @@ -1299,10 +1287,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, (&intinfo, argp, sizeof(cciss_coalint_struct))) return -EFAULT; if ((intinfo.delay == 0) && (intinfo.count == 0)) - { -// printk("cciss_ioctl: delay and count cannot be 0\n"); return -EINVAL; - } spin_lock_irqsave(&h->lock, flags); /* Update the field, and then ring the doorbell */ writel(intinfo.delay, @@ -1814,9 +1799,7 @@ static void cciss_softirq_done(struct request *rq) ++sg_index; } -#ifdef CCISS_DEBUG - printk("Done with %p\n", rq); -#endif /* CCISS_DEBUG */ + dev_dbg(&h->pdev->dev, "Done with %p\n", rq); /* set the residual count for pc requests */ if (rq->cmd_type == REQ_TYPE_BLOCK_PC) @@ -2029,7 +2012,7 @@ static void cciss_update_drive_info(ctlr_info_t *h, int drv_index, * (unless it's the first disk (for the controller node). */ if (h->drv[drv_index]->raid_level != -1 && drv_index != 0) { - printk(KERN_WARNING "disk %d has changed.\n", drv_index); + dev_warn(&h->pdev->dev, "disk %d has changed.\n", drv_index); spin_lock_irqsave(&h->lock, flags); h->drv[drv_index]->busy_configuring = 1; spin_unlock_irqrestore(&h->lock, flags); @@ -2082,8 +2065,8 @@ static void cciss_update_drive_info(ctlr_info_t *h, int drv_index, if (cciss_add_disk(h, disk, drv_index) != 0) { cciss_free_gendisk(h, drv_index); cciss_free_drive_info(h, drv_index); - printk(KERN_WARNING "cciss:%d could not update " - "disk %d\n", h->ctlr, drv_index); + dev_warn(&h->pdev->dev, "could not update disk %d\n", + drv_index); --h->num_luns; } } @@ -2093,7 +2076,7 @@ freeret: kfree(drvinfo); return; mem_msg: - printk(KERN_ERR "cciss: out of memory\n"); + dev_err(&h->pdev->dev, "out of memory\n"); goto freeret; } @@ -2185,9 +2168,9 @@ static int cciss_add_gendisk(ctlr_info_t *h, unsigned char lunid[], h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); if (!h->gendisk[drv_index]) { - printk(KERN_ERR "cciss%d: could not " - "allocate a new disk %d\n", - h->ctlr, drv_index); + dev_err(&h->pdev->dev, + "could not allocate a new disk %d\n", + drv_index); goto err_free_drive_info; } } @@ -2238,8 +2221,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) cciss_free_gendisk(h, drv_index); cciss_free_drive_info(h, drv_index); error: - printk(KERN_WARNING "cciss%d: could not " - "add disk 0.\n", h->ctlr); + dev_warn(&h->pdev->dev, "could not add disk 0.\n"); return; } @@ -2287,8 +2269,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, if (return_code == IO_OK) listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); else { /* reading number of logical volumes failed */ - printk(KERN_WARNING "cciss: report logical volume" - " command failed\n"); + dev_warn(&h->pdev->dev, + "report logical volume command failed\n"); listlength = 0; goto freeret; } @@ -2296,7 +2278,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time, num_luns = listlength / 8; /* 8 bytes per entry */ if (num_luns > CISS_MAX_LUN) { num_luns = CISS_MAX_LUN; - printk(KERN_WARNING "cciss: more luns configured" + dev_warn(&h->pdev->dev, "more luns configured" " on controller than can be handled by" " this driver.\n"); } @@ -2380,7 +2362,7 @@ freeret: */ return -1; mem_msg: - printk(KERN_ERR "cciss: out of memory\n"); + dev_err(&h->pdev->dev, "out of memory\n"); h->busy_configuring = 0; goto freeret; } @@ -2587,9 +2569,7 @@ static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, c->Request.Timeout = 0; break; default: - printk(KERN_WARNING - "cciss%d: Unknown Command 0x%c\n", - h->ctlr, cmd); + dev_warn(&h->pdev->dev, "Unknown Command 0x%c\n", cmd); return IO_ERROR; } } else if (cmd_type == TYPE_MSG) { @@ -2621,14 +2601,12 @@ static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff, c->Request.CDB[0] = cmd; break; default: - printk(KERN_WARNING - "cciss%d: unknown message type %d\n", - h->ctlr, cmd); + dev_warn(&h->pdev->dev, + "unknown message type %d\n", cmd); return IO_ERROR; } } else { - printk(KERN_WARNING - "cciss%d: unknown command type %d\n", h->ctlr, cmd_type); + dev_warn(&h->pdev->dev, "unknown command type %d\n", cmd_type); return IO_ERROR; } /* Fill in the scatter gather information */ @@ -2656,15 +2634,14 @@ static int check_target_status(ctlr_info_t *h, CommandList_struct *c) default: if (check_for_unit_attention(h, c)) return IO_NEEDS_RETRY; - printk(KERN_WARNING "cciss%d: cmd 0x%02x " + dev_warn(&h->pdev->dev, "cmd 0x%02x " "check condition, sense key = 0x%02x\n", - h->ctlr, c->Request.CDB[0], - c->err_info->SenseInfo[2]); + c->Request.CDB[0], c->err_info->SenseInfo[2]); } break; default: - printk(KERN_WARNING "cciss%d: cmd 0x%02x" - "scsi status = 0x%02x\n", h->ctlr, + dev_warn(&h->pdev->dev, "cmd 0x%02x" + "scsi status = 0x%02x\n", c->Request.CDB[0], c->err_info->ScsiStatus); break; } @@ -2687,43 +2664,42 @@ static int process_sendcmd_error(ctlr_info_t *h, CommandList_struct *c) /* expected for inquiry and report lun commands */ break; case CMD_INVALID: - printk(KERN_WARNING "cciss: cmd 0x%02x is " + dev_warn(&h->pdev->dev, "cmd 0x%02x is " "reported invalid\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cmd 0x%02x has " - "protocol error \n", c->Request.CDB[0]); + dev_warn(&h->pdev->dev, "cmd 0x%02x has " + "protocol error\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_HARDWARE_ERR: - printk(KERN_WARNING "cciss: cmd 0x%02x had " + dev_warn(&h->pdev->dev, "cmd 0x%02x had " " hardware error\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cmd 0x%02x had " + dev_warn(&h->pdev->dev, "cmd 0x%02x had " "connection lost\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_ABORTED: - printk(KERN_WARNING "cciss: cmd 0x%02x was " + dev_warn(&h->pdev->dev, "cmd 0x%02x was " "aborted\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cmd 0x%02x reports " + dev_warn(&h->pdev->dev, "cmd 0x%02x reports " "abort failed\n", c->Request.CDB[0]); return_status = IO_ERROR; break; case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING - "cciss%d: unsolicited abort 0x%02x\n", h->ctlr, + dev_warn(&h->pdev->dev, "unsolicited abort 0x%02x\n", c->Request.CDB[0]); return_status = IO_NEEDS_RETRY; break; default: - printk(KERN_WARNING "cciss: cmd 0x%02x returned " + dev_warn(&h->pdev->dev, "cmd 0x%02x returned " "unknown status %x\n", c->Request.CDB[0], c->err_info->CommandStatus); return_status = IO_ERROR; @@ -2751,7 +2727,7 @@ resend_cmd2: if (return_status == IO_NEEDS_RETRY && c->retry_count < MAX_CMD_RETRIES) { - printk(KERN_WARNING "cciss%d: retrying 0x%02x\n", h->ctlr, + dev_warn(&h->pdev->dev, "retrying 0x%02x\n", c->Request.CDB[0]); c->retry_count++; /* erase the old error information */ @@ -2805,8 +2781,8 @@ static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, sizeof(*inq_buff), 0xC1, scsi3addr, TYPE_CMD); if (return_code == IO_OK) { if (inq_buff->data_byte[8] == 0xFF) { - printk(KERN_WARNING - "cciss: reading geometry failed, volume " + dev_warn(&h->pdev->dev, + "reading geometry failed, volume " "does not support reading geometry\n"); drv->heads = 255; drv->sectors = 32; /* Sectors per track */ @@ -2830,7 +2806,7 @@ static void cciss_geometry_inquiry(ctlr_info_t *h, int logvol, drv->cylinders = real_size; } } else { /* Get geometry failed */ - printk(KERN_WARNING "cciss: reading geometry failed\n"); + dev_warn(&h->pdev->dev, "reading geometry failed\n"); } } @@ -2844,7 +2820,7 @@ cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size, buf = kzalloc(sizeof(ReadCapdata_struct), GFP_KERNEL); if (!buf) { - printk(KERN_WARNING "cciss: out of memory\n"); + dev_warn(&h->pdev->dev, "out of memory\n"); return; } @@ -2855,7 +2831,7 @@ cciss_read_capacity(ctlr_info_t *h, int logvol, sector_t *total_size, *total_size = be32_to_cpu(*(__be32 *) buf->total_size); *block_size = be32_to_cpu(*(__be32 *) buf->block_size); } else { /* read capacity command failed */ - printk(KERN_WARNING "cciss: read capacity failed\n"); + dev_warn(&h->pdev->dev, "read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } @@ -2871,7 +2847,7 @@ static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, buf = kzalloc(sizeof(ReadCapdata_struct_16), GFP_KERNEL); if (!buf) { - printk(KERN_WARNING "cciss: out of memory\n"); + dev_warn(&h->pdev->dev, "out of memory\n"); return; } @@ -2883,11 +2859,11 @@ static void cciss_read_capacity_16(ctlr_info_t *h, int logvol, *total_size = be64_to_cpu(*(__be64 *) buf->total_size); *block_size = be32_to_cpu(*(__be32 *) buf->block_size); } else { /* read capacity command failed */ - printk(KERN_WARNING "cciss: read capacity failed\n"); + dev_warn(&h->pdev->dev, "read capacity failed\n"); *total_size = 0; *block_size = BLOCK_SIZE; } - printk(KERN_INFO " blocks= %llu block_size= %d\n", + dev_info(&h->pdev->dev, " blocks= %llu block_size= %d\n", (unsigned long long)*total_size+1, *block_size); kfree(buf); } @@ -2915,7 +2891,7 @@ static int cciss_revalidate(struct gendisk *disk) inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { - printk(KERN_WARNING "cciss: out of memory\n"); + dev_warn(&h->pdev->dev, "out of memory\n"); return 1; } if (h->cciss_read == CCISS_READ_10) { @@ -2959,7 +2935,7 @@ static void start_io(ctlr_info_t *h) c = hlist_entry(h->reqQ.first, CommandList_struct, list); /* can't do anything if fifo is full */ if ((h->access.fifo_full(h))) { - printk(KERN_WARNING "cciss: fifo full\n"); + dev_warn(&h->pdev->dev, "fifo full\n"); break; } @@ -3026,7 +3002,7 @@ static inline int evaluate_target_status(ctlr_info_t *h, if (cmd->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION) { if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) - printk(KERN_WARNING "cciss: cmd %p " + dev_warn(&h->pdev->dev, "cmd %p " "has SCSI Status 0x%x\n", cmd, cmd->err_info->ScsiStatus); return error_value; @@ -3047,7 +3023,7 @@ static inline int evaluate_target_status(ctlr_info_t *h, /* Not SG_IO or similar? */ if (cmd->rq->cmd_type != REQ_TYPE_BLOCK_PC) { if (error_value != 0) - printk(KERN_WARNING "cciss: cmd %p has CHECK CONDITION" + dev_warn(&h->pdev->dev, "cmd %p has CHECK CONDITION" " sense key = 0x%x\n", cmd, sense_key); return error_value; } @@ -3088,7 +3064,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, break; case CMD_DATA_UNDERRUN: if (cmd->rq->cmd_type == REQ_TYPE_FS) { - printk(KERN_WARNING "cciss: cmd %p has" + dev_warn(&h->pdev->dev, "cmd %p has" " completed with data underrun " "reported\n", cmd); cmd->rq->resid_len = cmd->err_info->ResidualCnt; @@ -3096,12 +3072,12 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, break; case CMD_DATA_OVERRUN: if (cmd->rq->cmd_type == REQ_TYPE_FS) - printk(KERN_WARNING "cciss: cmd %p has" + dev_warn(&h->pdev->dev, "cciss: cmd %p has" " completed with data overrun " "reported\n", cmd); break; case CMD_INVALID: - printk(KERN_WARNING "cciss: cmd %p is " + dev_warn(&h->pdev->dev, "cciss: cmd %p is " "reported invalid\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, @@ -3109,15 +3085,15 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, DID_PASSTHROUGH : DID_ERROR); break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: cmd %p has " - "protocol error \n", cmd); + dev_warn(&h->pdev->dev, "cciss: cmd %p has " + "protocol error\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? DID_PASSTHROUGH : DID_ERROR); break; case CMD_HARDWARE_ERR: - printk(KERN_WARNING "cciss: cmd %p had " + dev_warn(&h->pdev->dev, "cciss: cmd %p had " " hardware error\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, @@ -3125,7 +3101,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, DID_PASSTHROUGH : DID_ERROR); break; case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: cmd %p had " + dev_warn(&h->pdev->dev, "cciss: cmd %p had " "connection lost\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, @@ -3133,7 +3109,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, DID_PASSTHROUGH : DID_ERROR); break; case CMD_ABORTED: - printk(KERN_WARNING "cciss: cmd %p was " + dev_warn(&h->pdev->dev, "cciss: cmd %p was " "aborted\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, @@ -3141,7 +3117,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, DID_PASSTHROUGH : DID_ABORT); break; case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: cmd %p reports " + dev_warn(&h->pdev->dev, "cciss: cmd %p reports " "abort failed\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, @@ -3149,31 +3125,29 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd, DID_PASSTHROUGH : DID_ERROR); break; case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING "cciss%d: unsolicited " + dev_warn(&h->pdev->dev, "cciss%d: unsolicited " "abort %p\n", h->ctlr, cmd); if (cmd->retry_count < MAX_CMD_RETRIES) { retry_cmd = 1; - printk(KERN_WARNING - "cciss%d: retrying %p\n", h->ctlr, cmd); + dev_warn(&h->pdev->dev, "retrying %p\n", cmd); cmd->retry_count++; } else - printk(KERN_WARNING - "cciss%d: %p retried too " - "many times\n", h->ctlr, cmd); + dev_warn(&h->pdev->dev, + "%p retried too many times\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? DID_PASSTHROUGH : DID_ABORT); break; case CMD_TIMEOUT: - printk(KERN_WARNING "cciss: cmd %p timedout\n", cmd); + dev_warn(&h->pdev->dev, "cmd %p timedout\n", cmd); rq->errors = make_status_bytes(SAM_STAT_GOOD, cmd->err_info->CommandStatus, DRIVER_OK, (cmd->rq->cmd_type == REQ_TYPE_BLOCK_PC) ? DID_PASSTHROUGH : DID_ERROR); break; default: - printk(KERN_WARNING "cciss: cmd %p returned " + dev_warn(&h->pdev->dev, "cmd %p returned " "unknown status %x\n", cmd, cmd->err_info->CommandStatus); rq->errors = make_status_bytes(SAM_STAT_GOOD, @@ -3282,11 +3256,8 @@ static void do_cciss_request(struct request_queue *q) c->Request.CDB[0] = (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; start_blk = blk_rq_pos(creq); -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "ciss: sector =%d nr_sectors=%d\n", + dev_dbg(&h->pdev->dev, "sector =%d nr_sectors=%d\n", (int)blk_rq_pos(creq), (int)blk_rq_sectors(creq)); -#endif /* CCISS_DEBUG */ - sg_init_table(tmp_sg, h->maxsgentries); seg = blk_rq_map_sg(q, creq, tmp_sg); @@ -3326,11 +3297,9 @@ static void do_cciss_request(struct request_queue *q) if (seg > h->maxSG) h->maxSG = seg; -#ifdef CCISS_DEBUG - printk(KERN_DEBUG "cciss: Submitting %ld sectors in %d segments " + dev_dbg(&h->pdev->dev, "Submitting %u sectors in %d segments " "chained[%d]\n", blk_rq_sectors(creq), seg, chained); -#endif /* CCISS_DEBUG */ c->Header.SGTotal = seg + chained; if (seg <= h->max_cmd_sgentries) @@ -3373,7 +3342,8 @@ static void do_cciss_request(struct request_queue *q) c->Request.CDBLen = creq->cmd_len; memcpy(c->Request.CDB, creq->cmd, BLK_MAX_CDB); } else { - printk(KERN_WARNING "cciss%d: bad request type %d\n", h->ctlr, creq->cmd_type); + dev_warn(&h->pdev->dev, "bad request type %d\n", + creq->cmd_type); BUG(); } @@ -3675,18 +3645,17 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) switch (c->err_info->SenseInfo[12]) { case STATE_CHANGED: - printk(KERN_WARNING "cciss%d: a state change " - "detected, command retried\n", h->ctlr); + dev_warn(&h->pdev->dev, "a state change " + "detected, command retried\n"); return 1; break; case LUN_FAILED: - printk(KERN_WARNING "cciss%d: LUN failure " - "detected, action required\n", h->ctlr); + dev_warn(&h->pdev->dev, "LUN failure " + "detected, action required\n"); return 1; break; case REPORT_LUNS_CHANGED: - printk(KERN_WARNING "cciss%d: report LUN data " - "changed\n", h->ctlr); + dev_warn(&h->pdev->dev, "report LUN data changed\n"); /* * Here, we could call add_to_scan_list and wake up the scan thread, * except that it's quite likely that we will get more than one @@ -3706,19 +3675,18 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) return 1; break; case POWER_OR_RESET: - printk(KERN_WARNING "cciss%d: a power on " - "or device reset detected\n", h->ctlr); + dev_warn(&h->pdev->dev, + "a power on or device reset detected\n"); return 1; break; case UNIT_ATTENTION_CLEARED: - printk(KERN_WARNING "cciss%d: unit attention " - "cleared by another initiator\n", h->ctlr); + dev_warn(&h->pdev->dev, + "unit attention cleared by another initiator\n"); return 1; break; default: - printk(KERN_WARNING "cciss%d: unknown " - "unit attention detected\n", h->ctlr); - return 1; + dev_warn(&h->pdev->dev, "unknown unit attention detected\n"); + return 1; } } @@ -3727,38 +3695,40 @@ static int check_for_unit_attention(ctlr_info_t *h, CommandList_struct *c) * the io functions. * This is for debug only. */ -static void print_cfg_table(CfgTable_struct *tb) +static void print_cfg_table(ctlr_info_t *h) { -#ifdef CCISS_DEBUG int i; char temp_name[17]; + CfgTable_struct *tb = h->cfgtable; - printk("Controller Configuration information\n"); - printk("------------------------------------\n"); + dev_dbg(&h->pdev->dev, "Controller Configuration information\n"); + dev_dbg(&h->pdev->dev, "------------------------------------\n"); for (i = 0; i < 4; i++) temp_name[i] = readb(&(tb->Signature[i])); temp_name[4] = '\0'; - printk(" Signature = %s\n", temp_name); - printk(" Spec Number = %d\n", readl(&(tb->SpecValence))); - printk(" Transport methods supported = 0x%x\n", + dev_dbg(&h->pdev->dev, " Signature = %s\n", temp_name); + dev_dbg(&h->pdev->dev, " Spec Number = %d\n", + readl(&(tb->SpecValence))); + dev_dbg(&h->pdev->dev, " Transport methods supported = 0x%x\n", readl(&(tb->TransportSupport))); - printk(" Transport methods active = 0x%x\n", + dev_dbg(&h->pdev->dev, " Transport methods active = 0x%x\n", readl(&(tb->TransportActive))); - printk(" Requested transport Method = 0x%x\n", + dev_dbg(&h->pdev->dev, " Requested transport Method = 0x%x\n", readl(&(tb->HostWrite.TransportRequest))); - printk(" Coalesce Interrupt Delay = 0x%x\n", + dev_dbg(&h->pdev->dev, " Coalesce Interrupt Delay = 0x%x\n", readl(&(tb->HostWrite.CoalIntDelay))); - printk(" Coalesce Interrupt Count = 0x%x\n", + dev_dbg(&h->pdev->dev, " Coalesce Interrupt Count = 0x%x\n", readl(&(tb->HostWrite.CoalIntCount))); - printk(" Max outstanding commands = 0x%d\n", + dev_dbg(&h->pdev->dev, " Max outstanding commands = 0x%d\n", readl(&(tb->CmdsOutMax))); - printk(" Bus Types = 0x%x\n", readl(&(tb->BusTypes))); + dev_dbg(&h->pdev->dev, " Bus Types = 0x%x\n", + readl(&(tb->BusTypes))); for (i = 0; i < 16; i++) temp_name[i] = readb(&(tb->ServerName[i])); temp_name[16] = '\0'; - printk(" Server Name = %s\n", temp_name); - printk(" Heartbeat Counter = 0x%x\n\n\n", readl(&(tb->HeartBeat))); -#endif /* CCISS_DEBUG */ + dev_dbg(&h->pdev->dev, " Server Name = %s\n", temp_name); + dev_dbg(&h->pdev->dev, " Heartbeat Counter = 0x%x\n\n\n", + readl(&(tb->HeartBeat))); } static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) @@ -3783,7 +3753,7 @@ static int find_PCI_BAR_index(struct pci_dev *pdev, unsigned long pci_bar_addr) offset += 8; break; default: /* reserved in PCI 2.2 */ - printk(KERN_WARNING + dev_warn(&pdev->dev, "Base address is invalid\n"); return -1; break; @@ -3908,7 +3878,7 @@ static __devinit void cciss_enter_performant_mode(ctlr_info_t *h) cciss_wait_for_mode_change_ack(h); register_value = readl(&(h->cfgtable->TransportActive)); if (!(register_value & CFGTBL_Trans_Performant)) - printk(KERN_WARNING "cciss: unable to get board into" + dev_warn(&h->pdev->dev, "cciss: unable to get board into" " performant mode\n"); } @@ -3923,14 +3893,13 @@ static void __devinit cciss_put_controller_into_performant_mode(ctlr_info_t *h) if (!(trans_support & PERFORMANT_MODE)) return; - printk(KERN_WARNING "cciss%d: Placing controller into " - "performant mode\n", h->ctlr); + dev_dbg(&h->pdev->dev, "Placing controller into performant mode\n"); /* Performant mode demands commands on a 32 byte boundary * pci_alloc_consistent aligns on page boundarys already. * Just need to check if divisible by 32 */ if ((sizeof(CommandList_struct) % 32) != 0) { - printk(KERN_WARNING "%s %d %s\n", + dev_warn(&h->pdev->dev, "%s %d %s\n", "cciss info: command size[", (int)sizeof(CommandList_struct), "] not divisible by 32, no performant mode..\n"); @@ -3995,12 +3964,12 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *h) return; } if (err > 0) { - printk(KERN_WARNING "cciss: only %d MSI-X vectors " - "available\n", err); + dev_warn(&h->pdev->dev, + "only %d MSI-X vectors available\n", err); goto default_int_mode; } else { - printk(KERN_WARNING "cciss: MSI-X init failed %d\n", - err); + dev_warn(&h->pdev->dev, + "MSI-X init failed %d\n", err); goto default_int_mode; } } @@ -4008,7 +3977,7 @@ static void __devinit cciss_interrupt_mode(ctlr_info_t *h) if (!pci_enable_msi(h->pdev)) h->msi_vector = 1; else - printk(KERN_WARNING "cciss: MSI init failed\n"); + dev_warn(&h->pdev->dev, "MSI init failed\n"); } default_int_mode: #endif /* CONFIG_PCI_MSI */ @@ -4210,28 +4179,24 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) h->access = *(products[prod_index].access); if (cciss_board_disabled(h)) { - printk(KERN_WARNING - "cciss: controller appears to be disabled\n"); + dev_warn(&h->pdev->dev, "controller appears to be disabled\n"); return -ENODEV; } err = pci_enable_device(h->pdev); if (err) { - printk(KERN_ERR "cciss: Unable to Enable PCI device\n"); + dev_warn(&h->pdev->dev, "Unable to Enable PCI device\n"); return err; } err = pci_request_regions(h->pdev, "cciss"); if (err) { - printk(KERN_ERR "cciss: Cannot obtain PCI resources, " - "aborting\n"); + dev_warn(&h->pdev->dev, + "Cannot obtain PCI resources, aborting\n"); return err; } -#ifdef CCISS_DEBUG - printk(KERN_INFO "command = %x\n", command); - printk(KERN_INFO "irq = %x\n", h->pdev->irq); - printk(KERN_INFO "board_id = %x\n", h->board_id); -#endif /* CCISS_DEBUG */ + dev_dbg(&h->pdev->dev, "irq = %x\n", h->pdev->irq); + dev_dbg(&h->pdev->dev, "board_id = %x\n", h->board_id); /* If the kernel supports MSI/MSI-X we will try to enable that functionality, * else we use the IO-APIC interrupt assigned to us by system ROM. @@ -4251,7 +4216,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *h) err = cciss_find_cfgtables(h); if (err) goto err_out_free_res; - print_cfg_table(h->cfgtable); + print_cfg_table(h); cciss_find_board_params(h); if (!CISS_signature_present(h)) { @@ -4281,7 +4246,7 @@ err_out_free_res: /* Function to find the first free pointer into our hba[] array * Returns -1 if no free entries are left. */ -static int alloc_cciss_hba(void) +static int alloc_cciss_hba(struct pci_dev *pdev) { int i; @@ -4296,11 +4261,11 @@ static int alloc_cciss_hba(void) return i; } } - printk(KERN_WARNING "cciss: This driver supports a maximum" + dev_warn(&pdev->dev, "This driver supports a maximum" " of %d controllers.\n", MAX_CTLR); return -1; Enomem: - printk(KERN_ERR "cciss: out of memory.\n"); + dev_warn(&pdev->dev, "out of memory.\n"); return -1; } @@ -4388,7 +4353,8 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u /* we leak the DMA buffer here ... no choice since the controller could still complete the command. */ if (i == 10) { - printk(KERN_ERR "cciss: controller message %02x:%02x timed out\n", + dev_err(&pdev->dev, + "controller message %02x:%02x timed out\n", opcode, type); return -ETIMEDOUT; } @@ -4396,12 +4362,12 @@ static __devinit int cciss_message(struct pci_dev *pdev, unsigned char opcode, u pci_free_consistent(pdev, cmd_sz, cmd, paddr64); if (tag & 2) { - printk(KERN_ERR "cciss: controller message %02x:%02x failed\n", + dev_err(&pdev->dev, "controller message %02x:%02x failed\n", opcode, type); return -EIO; } - printk(KERN_INFO "cciss: controller message %02x:%02x succeeded\n", + dev_info(&pdev->dev, "controller message %02x:%02x succeeded\n", opcode, type); return 0; } @@ -4422,7 +4388,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) if (pos) { pci_read_config_word(pdev, msi_control_reg(pos), &control); if (control & PCI_MSI_FLAGS_ENABLE) { - printk(KERN_INFO "cciss: resetting MSI\n"); + dev_info(&pdev->dev, "resetting MSI\n"); pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSI_FLAGS_ENABLE); } } @@ -4431,7 +4397,7 @@ static __devinit int cciss_reset_msi(struct pci_dev *pdev) if (pos) { pci_read_config_word(pdev, msi_control_reg(pos), &control); if (control & PCI_MSIX_FLAGS_ENABLE) { - printk(KERN_INFO "cciss: resetting MSI-X\n"); + dev_info(&pdev->dev, "resetting MSI-X\n"); pci_write_config_word(pdev, msi_control_reg(pos), control & ~PCI_MSIX_FLAGS_ENABLE); } } @@ -4664,7 +4630,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, rc = cciss_init_reset_devices(pdev); if (rc) return rc; - i = alloc_cciss_hba(); + i = alloc_cciss_hba(pdev); if (i < 0) return -1; @@ -4692,7 +4658,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) dac = 0; else { - printk(KERN_ERR "cciss: no suitable DMA available\n"); + dev_err(&h->pdev->dev, "no suitable DMA available\n"); goto clean1; } @@ -4705,8 +4671,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, h->major = COMPAQ_CISS_MAJOR + i; rc = register_blkdev(h->major, h->devname); if (rc == -EBUSY || rc == -EINVAL) { - printk(KERN_ERR - "cciss: Unable to get major number %d for %s " + dev_err(&h->pdev->dev, + "Unable to get major number %d for %s " "on hba %d\n", h->major, h->devname, i); goto clean1; } else { @@ -4720,20 +4686,20 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, if (request_irq(h->intr[PERF_MODE_INT], do_cciss_msix_intr, IRQF_DISABLED, h->devname, h)) { - printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", + dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", h->intr[PERF_MODE_INT], h->devname); goto clean2; } } else { if (request_irq(h->intr[PERF_MODE_INT], do_cciss_intx, IRQF_DISABLED, h->devname, h)) { - printk(KERN_ERR "cciss: Unable to get irq %d for %s\n", + dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n", h->intr[PERF_MODE_INT], h->devname); goto clean2; } } - printk(KERN_INFO "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", + dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n", h->devname, pdev->device, pci_name(pdev), h->intr[PERF_MODE_INT], dac ? "" : " not"); @@ -4751,7 +4717,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, if ((h->cmd_pool_bits == NULL) || (h->cmd_pool == NULL) || (h->errinfo_pool == NULL)) { - printk(KERN_ERR "cciss: out of memory"); + dev_err(&h->pdev->dev, "out of memory"); goto clean4; } @@ -4764,8 +4730,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, h->maxsgentries, GFP_KERNEL); if (h->scatter_list[k] == NULL) { - printk(KERN_ERR "cciss%d: could not allocate " - "s/g lists\n", i); + dev_err(&h->pdev->dev, + "could not allocate s/g lists\n"); goto clean4; } } @@ -4800,7 +4766,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, /* Get the firmware version */ inq_buff = kzalloc(sizeof(InquiryData_struct), GFP_KERNEL); if (inq_buff == NULL) { - printk(KERN_ERR "cciss: out of memory\n"); + dev_err(&h->pdev->dev, "out of memory\n"); goto clean4; } @@ -4812,7 +4778,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, h->firm_ver[2] = inq_buff->data_byte[34]; h->firm_ver[3] = inq_buff->data_byte[35]; } else { /* send command failed */ - printk(KERN_WARNING "cciss: unable to determine firmware" + dev_warn(&h->pdev->dev, "unable to determine firmware" " version of controller\n"); } kfree(inq_buff); @@ -4869,9 +4835,7 @@ static void cciss_shutdown(struct pci_dev *pdev) h = pci_get_drvdata(pdev); flush_buf = kzalloc(4, GFP_KERNEL); if (!flush_buf) { - printk(KERN_WARNING - "cciss:%d cache not flushed, out of memory.\n", - h->ctlr); + dev_warn(&h->pdev->dev, "cache not flushed, out of memory.\n"); return; } /* write all data in the battery backed cache to disk */ @@ -4880,8 +4844,7 @@ static void cciss_shutdown(struct pci_dev *pdev) 4, 0, CTLR_LUNID, TYPE_CMD); kfree(flush_buf); if (return_code != IO_OK) - printk(KERN_WARNING "cciss%d: Error flushing cache\n", - h->ctlr); + dev_warn(&h->pdev->dev, "Error flushing cache\n"); h->access.set_intr_mask(h, CCISS_INTR_OFF); free_irq(h->intr[PERF_MODE_INT], h); } @@ -4892,15 +4855,14 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) int i, j; if (pci_get_drvdata(pdev) == NULL) { - printk(KERN_ERR "cciss: Unable to remove device \n"); + dev_err(&pdev->dev, "Unable to remove device\n"); return; } h = pci_get_drvdata(pdev); i = h->ctlr; if (hba[i] == NULL) { - printk(KERN_ERR "cciss: device appears to " - "already be removed\n"); + dev_err(&pdev->dev, "device appears to already be removed\n"); return; } @@ -5021,8 +4983,8 @@ static void __exit cciss_cleanup(void) /* double check that all controller entrys have been removed */ for (i = 0; i < MAX_CTLR; i++) { if (hba[i] != NULL) { - printk(KERN_WARNING "cciss: had to remove" - " controller %d\n", i); + dev_warn(&hba[i]->pdev->dev, + "had to remove controller\n"); cciss_remove_one(hba[i]->pdev); } } diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index 9fe0d8ffc90..575495f3c4b 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c @@ -192,7 +192,8 @@ scsi_cmd_free(ctlr_info_t *h, CommandList_struct *c) stk = &sa->cmd_stack; stk->top++; if (stk->top >= CMD_STACK_SIZE) { - printk("cciss: scsi_cmd_free called too many times.\n"); + dev_err(&h->pdev->dev, + "scsi_cmd_free called too many times.\n"); BUG(); } stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) c; @@ -245,10 +246,9 @@ scsi_cmd_stack_free(ctlr_info_t *h) sa = h->scsi_ctlr; stk = &sa->cmd_stack; if (stk->top != CMD_STACK_SIZE-1) { - printk( "cciss: %d scsi commands are still outstanding.\n", + dev_warn(&h->pdev->dev, + "bug: %d scsi commands are still outstanding.\n", CMD_STACK_SIZE - stk->top); - // BUG(); - printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk); } size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE; @@ -382,8 +382,8 @@ cciss_scsi_add_entry(ctlr_info_t *h, int hostno, unsigned char addr1[8], addr2[8]; if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { - printk("cciss%d: Too many devices, " - "some will be inaccessible.\n", h->ctlr); + dev_warn(&h->pdev->dev, "Too many devices, " + "some will be inaccessible.\n"); return -1; } @@ -439,8 +439,8 @@ cciss_scsi_add_entry(ctlr_info_t *h, int hostno, know our hostno and we don't want to print anything first time anyway (the scsi layer's inquiries will show that info) */ if (hostno != -1) - printk("cciss%d: %s device c%db%dt%dl%d added.\n", - h->ctlr, scsi_device_type(sd->devtype), hostno, + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d added.\n", + scsi_device_type(sd->devtype), hostno, sd->bus, sd->target, sd->lun); return 0; } @@ -462,8 +462,8 @@ cciss_scsi_remove_entry(ctlr_info_t *h, int hostno, int entry, for (i = entry; i < ccissscsi[h->ctlr].ndevices-1; i++) ccissscsi[h->ctlr].dev[i] = ccissscsi[h->ctlr].dev[i+1]; ccissscsi[h->ctlr].ndevices--; - printk("cciss%d: %s device c%db%dt%dl%d removed.\n", - h->ctlr, scsi_device_type(sd.devtype), hostno, + dev_info(&h->pdev->dev, "%s device c%db%dt%dl%d removed.\n", + scsi_device_type(sd.devtype), hostno, sd.bus, sd.target, sd.lun); } @@ -536,8 +536,8 @@ adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, GFP_KERNEL); if (!added || !removed) { - printk(KERN_WARNING "cciss%d: Out of memory in " - "adjust_cciss_scsi_table\n", h->ctlr); + dev_warn(&h->pdev->dev, + "Out of memory in adjust_cciss_scsi_table\n"); goto free_and_out; } @@ -568,17 +568,14 @@ adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, if (found == 0) { /* device no longer present. */ changes++; - /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", - h->ctlr, scsi_device_type(csd->devtype), hostno, - csd->bus, csd->target, csd->lun); */ cciss_scsi_remove_entry(h, hostno, i, removed, &nremoved); /* remove ^^^, hence i not incremented */ } else if (found == 1) { /* device is different in some way */ changes++; - printk("cciss%d: device c%db%dt%dl%d has changed.\n", - h->ctlr, hostno, - csd->bus, csd->target, csd->lun); + dev_info(&h->pdev->dev, + "device c%db%dt%dl%d has changed.\n", + hostno, csd->bus, csd->target, csd->lun); cciss_scsi_remove_entry(h, hostno, i, removed, &nremoved); /* remove ^^^, hence i not incremented */ @@ -623,8 +620,8 @@ adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, } else if (found == 1) { /* should never happen... */ changes++; - printk(KERN_WARNING "cciss%d: device " - "unexpectedly changed\n", h->ctlr); + dev_warn(&h->pdev->dev, + "device unexpectedly changed\n"); /* but if it does happen, we just ignore that device */ } } @@ -648,9 +645,9 @@ adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, /* We don't expect to get here. */ /* future cmds to this device will get selection */ /* timeout as if the device was gone. */ - printk(KERN_WARNING "cciss%d: didn't find " + dev_warn(&h->pdev->dev, "didn't find " "c%db%dt%dl%d\n for removal.", - h->ctlr, hostno, removed[i].bus, + hostno, removed[i].bus, removed[i].target, removed[i].lun); } } @@ -662,10 +659,9 @@ adjust_cciss_scsi_table(ctlr_info_t *h, int hostno, added[i].target, added[i].lun); if (rc == 0) continue; - printk(KERN_WARNING "cciss%d: scsi_add_device " + dev_warn(&h->pdev->dev, "scsi_add_device " "c%db%dt%dl%d failed, device not added.\n", - h->ctlr, hostno, - added[i].bus, added[i].target, added[i].lun); + hostno, added[i].bus, added[i].target, added[i].lun); /* now we have to remove it from ccissscsi, */ /* since it didn't get added to scsi mid layer */ fixup_botched_add(h, added[i].scsi3addr); @@ -788,7 +784,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ break; case CMD_DATA_OVERRUN: - printk(KERN_WARNING "cciss: %p has" + dev_warn(&h->pdev->dev, "%p has" " completed with data overrun " "reported\n", c); break; @@ -804,43 +800,41 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, } break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: %p has " - "protocol error\n", c); + dev_warn(&h->pdev->dev, + "%p has protocol error\n", c); break; case CMD_HARDWARE_ERR: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: %p had " - " hardware error\n", c); + dev_warn(&h->pdev->dev, + "%p had hardware error\n", c); break; case CMD_CONNECTION_LOST: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: %p had " - "connection lost\n", c); + dev_warn(&h->pdev->dev, + "%p had connection lost\n", c); break; case CMD_ABORTED: cmd->result = DID_ABORT << 16; - printk(KERN_WARNING "cciss: %p was " - "aborted\n", c); + dev_warn(&h->pdev->dev, "%p was aborted\n", c); break; case CMD_ABORT_FAILED: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: %p reports " - "abort failed\n", c); + dev_warn(&h->pdev->dev, + "%p reports abort failed\n", c); break; case CMD_UNSOLICITED_ABORT: cmd->result = DID_ABORT << 16; - printk(KERN_WARNING "cciss: %p aborted " - "do to an unsolicited abort\n", c); + dev_warn(&h->pdev->dev, "%p aborted do to an " + "unsolicited abort\n", c); break; case CMD_TIMEOUT: cmd->result = DID_TIME_OUT << 16; - printk(KERN_WARNING "cciss: %p timedout\n", - c); + dev_warn(&h->pdev->dev, "%p timedout\n", c); break; default: cmd->result = DID_ERROR << 16; - printk(KERN_WARNING "cciss: %p returned " - "unknown status %x\n", c, + dev_warn(&h->pdev->dev, + "%p returned unknown status %x\n", c, ei->CommandStatus); } } @@ -956,7 +950,7 @@ cciss_scsi_do_simple_cmd(ctlr_info_t *h, } static void -cciss_scsi_interpret_error(CommandList_struct *c) +cciss_scsi_interpret_error(ctlr_info_t *h, CommandList_struct *c) { ErrorInfo_struct *ei; @@ -964,67 +958,64 @@ cciss_scsi_interpret_error(CommandList_struct *c) switch(ei->CommandStatus) { case CMD_TARGET_STATUS: - printk(KERN_WARNING "cciss: cmd %p has " - "completed with errors\n", c); - printk(KERN_WARNING "cciss: cmd %p " - "has SCSI Status = %x\n", - c, ei->ScsiStatus); + dev_warn(&h->pdev->dev, + "cmd %p has completed with errors\n", c); + dev_warn(&h->pdev->dev, + "cmd %p has SCSI Status = %x\n", + c, ei->ScsiStatus); if (ei->ScsiStatus == 0) - printk(KERN_WARNING - "cciss:SCSI status is abnormally zero. " + dev_warn(&h->pdev->dev, + "SCSI status is abnormally zero. " "(probably indicates selection timeout " "reported incorrectly due to a known " "firmware bug, circa July, 2001.)\n"); break; case CMD_DATA_UNDERRUN: /* let mid layer handle it. */ - printk("UNDERRUN\n"); + dev_info(&h->pdev->dev, "UNDERRUN\n"); break; case CMD_DATA_OVERRUN: - printk(KERN_WARNING "cciss: %p has" + dev_warn(&h->pdev->dev, "%p has" " completed with data overrun " "reported\n", c); break; case CMD_INVALID: { /* controller unfortunately reports SCSI passthru's */ /* to non-existent targets as invalid commands. */ - printk(KERN_WARNING "cciss: %p is " - "reported invalid (probably means " + dev_warn(&h->pdev->dev, + "%p is reported invalid (probably means " "target device no longer present)\n", c); /* print_bytes((unsigned char *) c, sizeof(*c), 1, 0); print_cmd(c); */ } break; case CMD_PROTOCOL_ERR: - printk(KERN_WARNING "cciss: %p has " - "protocol error\n", c); + dev_warn(&h->pdev->dev, "%p has protocol error\n", c); break; case CMD_HARDWARE_ERR: /* cmd->result = DID_ERROR << 16; */ - printk(KERN_WARNING "cciss: %p had " - " hardware error\n", c); + dev_warn(&h->pdev->dev, "%p had hardware error\n", c); break; case CMD_CONNECTION_LOST: - printk(KERN_WARNING "cciss: %p had " - "connection lost\n", c); + dev_warn(&h->pdev->dev, "%p had connection lost\n", c); break; case CMD_ABORTED: - printk(KERN_WARNING "cciss: %p was " - "aborted\n", c); + dev_warn(&h->pdev->dev, "%p was aborted\n", c); break; case CMD_ABORT_FAILED: - printk(KERN_WARNING "cciss: %p reports " - "abort failed\n", c); + dev_warn(&h->pdev->dev, + "%p reports abort failed\n", c); break; case CMD_UNSOLICITED_ABORT: - printk(KERN_WARNING "cciss: %p aborted " - "do to an unsolicited abort\n", c); + dev_warn(&h->pdev->dev, + "%p aborted do to an unsolicited abort\n", c); break; case CMD_TIMEOUT: - printk(KERN_WARNING "cciss: %p timedout\n", c); + dev_warn(&h->pdev->dev, "%p timedout\n", c); break; default: - printk(KERN_WARNING "cciss: %p returned " - "unknown status %x\n", c, ei->CommandStatus); + dev_warn(&h->pdev->dev, + "%p returned unknown status %x\n", + c, ei->CommandStatus); } } @@ -1063,7 +1054,7 @@ cciss_scsi_do_inquiry(ctlr_info_t *h, unsigned char *scsi3addr, if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { - cciss_scsi_interpret_error(c); + cciss_scsi_interpret_error(h, c); rc = -1; } spin_lock_irqsave(&h->lock, flags); @@ -1134,7 +1125,7 @@ cciss_scsi_do_report_phys_luns(ctlr_info_t *h, ei = c->err_info; if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { - cciss_scsi_interpret_error(c); + cciss_scsi_interpret_error(h, c); rc = -1; } spin_lock_irqsave(&h->lock, flags); @@ -1446,7 +1437,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd c = scsi_cmd_alloc(h); spin_unlock_irqrestore(&h->lock, flags); if (c == NULL) { /* trouble... */ - printk("scsi_cmd_alloc returned NULL!\n"); + dev_warn(&h->pdev->dev, "scsi_cmd_alloc returned NULL!\n"); /* FIXME: next 3 lines are -> BAD! <- */ cmd->result = DID_NO_CONNECT << 16; done(cmd); @@ -1502,7 +1493,7 @@ cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd break; default: - printk("cciss: unknown data direction: %d\n", + dev_warn(&h->pdev->dev, "unknown data direction: %d\n", cmd->sc_data_direction); BUG(); break; @@ -1552,8 +1543,7 @@ static int cciss_engage_scsi(ctlr_info_t *h) stk = &sa->cmd_stack; if (sa->registered) { - printk(KERN_INFO "cciss%d: SCSI subsystem already engaged.\n", - h->ctlr); + dev_info(&h->pdev->dev, "SCSI subsystem already engaged.\n"); spin_unlock_irqrestore(&h->lock, flags); return -ENXIO; } @@ -1586,8 +1576,8 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, c = cmd_alloc(h); if (!c) { - printk(KERN_WARNING "cciss%d: out of memory in " - "wait_for_device_to_become_ready.\n", h->ctlr); + dev_warn(&h->pdev->dev, "out of memory in " + "wait_for_device_to_become_ready.\n"); return IO_ERROR; } @@ -1631,16 +1621,16 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h, } } retry_tur: - printk(KERN_WARNING "cciss%d: Waiting %d secs " + dev_warn(&h->pdev->dev, "Waiting %d secs " "for device to become ready.\n", - h->ctlr, waittime / HZ); + waittime / HZ); rc = 1; /* device not ready. */ } if (rc) - printk("cciss%d: giving up on device.\n", h->ctlr); + dev_warn(&h->pdev->dev, "giving up on device.\n"); else - printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr); + dev_warn(&h->pdev->dev, "device is ready.\n"); cmd_free(h, c); return rc; @@ -1668,8 +1658,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; if (h == NULL) /* paranoia */ return FAILED; - printk(KERN_WARNING - "cciss%d: resetting tape drive or medium changer.\n", h->ctlr); + dev_warn(&h->pdev->dev, "resetting tape drive or medium changer.\n"); /* find the command that's giving us trouble */ cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble; if (cmd_in_trouble == NULL) /* paranoia */ @@ -1680,7 +1669,7 @@ static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd) TYPE_MSG); if (rc == 0 && wait_for_device_to_become_ready(h, lunaddr) == 0) return SUCCESS; - printk(KERN_WARNING "cciss%d: resetting device failed.\n", h->ctlr); + dev_warn(&h->pdev->dev, "resetting device failed.\n"); return FAILED; } @@ -1695,7 +1684,7 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) h = (ctlr_info_t *) scsicmd->device->host->hostdata[0]; if (h == NULL) /* paranoia */ return FAILED; - printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", h->ctlr); + dev_warn(&h->pdev->dev, "aborting tardy SCSI cmd\n"); /* find the command to be aborted */ cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble; -- cgit v1.2.3-70-g09d2 From 8112586063fe53958d60218631d661533f304504 Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Mon, 19 Jul 2010 13:46:54 -0500 Subject: cciss: cleanup interrupt_not_for_us cciss: cleanup interrupt_not_for_us In the case of MSI/MSIX interrutps, we don't need to check if the interrupt is for us, and in the case of the intx interrupt handler, when checking if the interrupt is for us, we don't need to check if we're using MSI/MSIX, we know we're not. Signed-off-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/block/cciss.c') diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 35a9f08cf74..fdf1b79eb34 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -3376,8 +3376,7 @@ static inline int interrupt_pending(ctlr_info_t *h) static inline long interrupt_not_for_us(ctlr_info_t *h) { - return !(h->msi_vector || h->msix_vector) && - ((h->access.intr_pending(h) == 0) || + return ((h->access.intr_pending(h) == 0) || (h->interrupts_enabled == 0)); } @@ -3470,10 +3469,6 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id) if (interrupt_not_for_us(h)) return IRQ_NONE; - /* - * If there are completed commands in the completion queue, - * we had better do something about it. - */ spin_lock_irqsave(&h->lock, flags); while (interrupt_pending(h)) { raw_tag = get_next_completion(h); @@ -3484,7 +3479,6 @@ static irqreturn_t do_cciss_intx(int irq, void *dev_id) raw_tag = process_nonindexed_cmd(h, raw_tag); } } - spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } @@ -3498,12 +3492,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) unsigned long flags; u32 raw_tag; - if (interrupt_not_for_us(h)) - return IRQ_NONE; - /* - * If there are completed commands in the completion queue, - * we had better do something about it. - */ spin_lock_irqsave(&h->lock, flags); raw_tag = get_next_completion(h); while (raw_tag != FIFO_EMPTY) { @@ -3512,7 +3500,6 @@ static irqreturn_t do_cciss_msix_intr(int irq, void *dev_id) else raw_tag = process_nonindexed_cmd(h, raw_tag); } - spin_unlock_irqrestore(&h->lock, flags); return IRQ_HANDLED; } -- cgit v1.2.3-70-g09d2