diff options
Diffstat (limited to 'drivers/scsi/megaraid.c')
-rw-r--r-- | drivers/scsi/megaraid.c | 63 |
1 files changed, 28 insertions, 35 deletions
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 61a6fd810bb4..578143e93a6f 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -362,6 +362,7 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) | |||
362 | adapter_t *adapter; | 362 | adapter_t *adapter; |
363 | scb_t *scb; | 363 | scb_t *scb; |
364 | int busy=0; | 364 | int busy=0; |
365 | unsigned long flags; | ||
365 | 366 | ||
366 | adapter = (adapter_t *)scmd->device->host->hostdata; | 367 | adapter = (adapter_t *)scmd->device->host->hostdata; |
367 | 368 | ||
@@ -377,23 +378,25 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) | |||
377 | * return 0 in that case. | 378 | * return 0 in that case. |
378 | */ | 379 | */ |
379 | 380 | ||
381 | spin_lock_irqsave(&adapter->lock, flags); | ||
380 | scb = mega_build_cmd(adapter, scmd, &busy); | 382 | scb = mega_build_cmd(adapter, scmd, &busy); |
383 | if (!scb) | ||
384 | goto out; | ||
381 | 385 | ||
382 | if(scb) { | 386 | scb->state |= SCB_PENDQ; |
383 | scb->state |= SCB_PENDQ; | 387 | list_add_tail(&scb->list, &adapter->pending_list); |
384 | list_add_tail(&scb->list, &adapter->pending_list); | ||
385 | 388 | ||
386 | /* | 389 | /* |
387 | * Check if the HBA is in quiescent state, e.g., during a | 390 | * Check if the HBA is in quiescent state, e.g., during a |
388 | * delete logical drive opertion. If it is, don't run | 391 | * delete logical drive opertion. If it is, don't run |
389 | * the pending_list. | 392 | * the pending_list. |
390 | */ | 393 | */ |
391 | if(atomic_read(&adapter->quiescent) == 0) { | 394 | if (atomic_read(&adapter->quiescent) == 0) |
392 | mega_runpendq(adapter); | 395 | mega_runpendq(adapter); |
393 | } | ||
394 | return 0; | ||
395 | } | ||
396 | 396 | ||
397 | busy = 0; | ||
398 | out: | ||
399 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
397 | return busy; | 400 | return busy; |
398 | } | 401 | } |
399 | 402 | ||
@@ -661,7 +664,7 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) | |||
661 | sg->offset; | 664 | sg->offset; |
662 | } else | 665 | } else |
663 | buf = cmd->request_buffer; | 666 | buf = cmd->request_buffer; |
664 | memset(cmd->request_buffer, 0, cmd->cmnd[4]); | 667 | memset(buf, 0, cmd->cmnd[4]); |
665 | if (cmd->use_sg) { | 668 | if (cmd->use_sg) { |
666 | struct scatterlist *sg; | 669 | struct scatterlist *sg; |
667 | 670 | ||
@@ -1683,7 +1686,7 @@ mega_rundoneq (adapter_t *adapter) | |||
1683 | 1686 | ||
1684 | list_for_each(pos, &adapter->completed_list) { | 1687 | list_for_each(pos, &adapter->completed_list) { |
1685 | 1688 | ||
1686 | Scsi_Pointer* spos = (Scsi_Pointer *)pos; | 1689 | struct scsi_pointer* spos = (struct scsi_pointer *)pos; |
1687 | 1690 | ||
1688 | cmd = list_entry(spos, Scsi_Cmnd, SCp); | 1691 | cmd = list_entry(spos, Scsi_Cmnd, SCp); |
1689 | cmd->scsi_done(cmd); | 1692 | cmd->scsi_done(cmd); |
@@ -1981,7 +1984,7 @@ megaraid_reset(struct scsi_cmnd *cmd) | |||
1981 | mc.cmd = MEGA_CLUSTER_CMD; | 1984 | mc.cmd = MEGA_CLUSTER_CMD; |
1982 | mc.opcode = MEGA_RESET_RESERVATIONS; | 1985 | mc.opcode = MEGA_RESET_RESERVATIONS; |
1983 | 1986 | ||
1984 | if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { | 1987 | if( mega_internal_command(adapter, &mc, NULL) != 0 ) { |
1985 | printk(KERN_WARNING | 1988 | printk(KERN_WARNING |
1986 | "megaraid: reservation reset failed.\n"); | 1989 | "megaraid: reservation reset failed.\n"); |
1987 | } | 1990 | } |
@@ -3011,7 +3014,7 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) | |||
3011 | mc.cmd = FC_NEW_CONFIG; | 3014 | mc.cmd = FC_NEW_CONFIG; |
3012 | mc.opcode = OP_DCMD_READ_CONFIG; | 3015 | mc.opcode = OP_DCMD_READ_CONFIG; |
3013 | 3016 | ||
3014 | if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { | 3017 | if( mega_internal_command(adapter, &mc, NULL) ) { |
3015 | 3018 | ||
3016 | len = sprintf(page, "40LD read config failed.\n"); | 3019 | len = sprintf(page, "40LD read config failed.\n"); |
3017 | 3020 | ||
@@ -3029,11 +3032,11 @@ proc_rdrv(adapter_t *adapter, char *page, int start, int end ) | |||
3029 | else { | 3032 | else { |
3030 | mc.cmd = NEW_READ_CONFIG_8LD; | 3033 | mc.cmd = NEW_READ_CONFIG_8LD; |
3031 | 3034 | ||
3032 | if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) { | 3035 | if( mega_internal_command(adapter, &mc, NULL) ) { |
3033 | 3036 | ||
3034 | mc.cmd = READ_CONFIG_8LD; | 3037 | mc.cmd = READ_CONFIG_8LD; |
3035 | 3038 | ||
3036 | if( mega_internal_command(adapter, LOCK_INT, &mc, | 3039 | if( mega_internal_command(adapter, &mc, |
3037 | NULL) ){ | 3040 | NULL) ){ |
3038 | 3041 | ||
3039 | len = sprintf(page, | 3042 | len = sprintf(page, |
@@ -3632,7 +3635,7 @@ megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, | |||
3632 | /* | 3635 | /* |
3633 | * Issue the command | 3636 | * Issue the command |
3634 | */ | 3637 | */ |
3635 | mega_internal_command(adapter, LOCK_INT, &mc, pthru); | 3638 | mega_internal_command(adapter, &mc, pthru); |
3636 | 3639 | ||
3637 | rval = mega_n_to_m((void __user *)arg, &mc); | 3640 | rval = mega_n_to_m((void __user *)arg, &mc); |
3638 | 3641 | ||
@@ -3715,7 +3718,7 @@ freemem_and_return: | |||
3715 | /* | 3718 | /* |
3716 | * Issue the command | 3719 | * Issue the command |
3717 | */ | 3720 | */ |
3718 | mega_internal_command(adapter, LOCK_INT, &mc, NULL); | 3721 | mega_internal_command(adapter, &mc, NULL); |
3719 | 3722 | ||
3720 | rval = mega_n_to_m((void __user *)arg, &mc); | 3723 | rval = mega_n_to_m((void __user *)arg, &mc); |
3721 | 3724 | ||
@@ -4234,7 +4237,7 @@ mega_do_del_logdrv(adapter_t *adapter, int logdrv) | |||
4234 | mc.opcode = OP_DEL_LOGDRV; | 4237 | mc.opcode = OP_DEL_LOGDRV; |
4235 | mc.subopcode = logdrv; | 4238 | mc.subopcode = logdrv; |
4236 | 4239 | ||
4237 | rval = mega_internal_command(adapter, LOCK_INT, &mc, NULL); | 4240 | rval = mega_internal_command(adapter, &mc, NULL); |
4238 | 4241 | ||
4239 | /* log this event */ | 4242 | /* log this event */ |
4240 | if(rval) { | 4243 | if(rval) { |
@@ -4367,7 +4370,7 @@ mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle) | |||
4367 | 4370 | ||
4368 | mc.xferaddr = (u32)dma_handle; | 4371 | mc.xferaddr = (u32)dma_handle; |
4369 | 4372 | ||
4370 | if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) { | 4373 | if ( mega_internal_command(adapter, &mc, NULL) != 0 ) { |
4371 | return -1; | 4374 | return -1; |
4372 | } | 4375 | } |
4373 | 4376 | ||
@@ -4435,7 +4438,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, | |||
4435 | mc.cmd = MEGA_MBOXCMD_PASSTHRU; | 4438 | mc.cmd = MEGA_MBOXCMD_PASSTHRU; |
4436 | mc.xferaddr = (u32)pthru_dma_handle; | 4439 | mc.xferaddr = (u32)pthru_dma_handle; |
4437 | 4440 | ||
4438 | rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru); | 4441 | rval = mega_internal_command(adapter, &mc, pthru); |
4439 | 4442 | ||
4440 | pci_free_consistent(pdev, sizeof(mega_passthru), pthru, | 4443 | pci_free_consistent(pdev, sizeof(mega_passthru), pthru, |
4441 | pthru_dma_handle); | 4444 | pthru_dma_handle); |
@@ -4449,7 +4452,6 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, | |||
4449 | /** | 4452 | /** |
4450 | * mega_internal_command() | 4453 | * mega_internal_command() |
4451 | * @adapter - pointer to our soft state | 4454 | * @adapter - pointer to our soft state |
4452 | * @ls - the scope of the exclusion lock. | ||
4453 | * @mc - the mailbox command | 4455 | * @mc - the mailbox command |
4454 | * @pthru - Passthru structure for DCDB commands | 4456 | * @pthru - Passthru structure for DCDB commands |
4455 | * | 4457 | * |
@@ -4463,8 +4465,7 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, | |||
4463 | * Note: parameter 'pthru' is null for non-passthru commands. | 4465 | * Note: parameter 'pthru' is null for non-passthru commands. |
4464 | */ | 4466 | */ |
4465 | static int | 4467 | static int |
4466 | mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, | 4468 | mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) |
4467 | mega_passthru *pthru ) | ||
4468 | { | 4469 | { |
4469 | Scsi_Cmnd *scmd; | 4470 | Scsi_Cmnd *scmd; |
4470 | struct scsi_device *sdev; | 4471 | struct scsi_device *sdev; |
@@ -4508,15 +4509,8 @@ mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc, | |||
4508 | 4509 | ||
4509 | scb->idx = CMDID_INT_CMDS; | 4510 | scb->idx = CMDID_INT_CMDS; |
4510 | 4511 | ||
4511 | /* | ||
4512 | * Get the lock only if the caller has not acquired it already | ||
4513 | */ | ||
4514 | if( ls == LOCK_INT ) spin_lock_irqsave(&adapter->lock, flags); | ||
4515 | |||
4516 | megaraid_queue(scmd, mega_internal_done); | 4512 | megaraid_queue(scmd, mega_internal_done); |
4517 | 4513 | ||
4518 | if( ls == LOCK_INT ) spin_unlock_irqrestore(&adapter->lock, flags); | ||
4519 | |||
4520 | wait_for_completion(&adapter->int_waitq); | 4514 | wait_for_completion(&adapter->int_waitq); |
4521 | 4515 | ||
4522 | rval = scmd->result; | 4516 | rval = scmd->result; |
@@ -4683,7 +4677,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4683 | 4677 | ||
4684 | adapter->flag = flag; | 4678 | adapter->flag = flag; |
4685 | spin_lock_init(&adapter->lock); | 4679 | spin_lock_init(&adapter->lock); |
4686 | scsi_assign_lock(host, &adapter->lock); | ||
4687 | 4680 | ||
4688 | host->cmd_per_lun = max_cmd_per_lun; | 4681 | host->cmd_per_lun = max_cmd_per_lun; |
4689 | host->max_sectors = max_sectors_per_io; | 4682 | host->max_sectors = max_sectors_per_io; |