diff options
Diffstat (limited to 'drivers/scsi/megaraid.c')
-rw-r--r-- | drivers/scsi/megaraid.c | 120 |
1 files changed, 31 insertions, 89 deletions
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 816db12ef5d5..b7770516f4c2 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -531,13 +531,6 @@ mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy) | |||
531 | int target = 0; | 531 | int target = 0; |
532 | int ldrv_num = 0; /* logical drive number */ | 532 | int ldrv_num = 0; /* logical drive number */ |
533 | 533 | ||
534 | |||
535 | /* | ||
536 | * filter the internal and ioctl commands | ||
537 | */ | ||
538 | if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) | ||
539 | return (scb_t *)cmd->host_scribble; | ||
540 | |||
541 | /* | 534 | /* |
542 | * We know what channels our logical drives are on - mega_find_card() | 535 | * We know what channels our logical drives are on - mega_find_card() |
543 | */ | 536 | */ |
@@ -1439,19 +1432,22 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) | |||
1439 | 1432 | ||
1440 | cmdid = completed[i]; | 1433 | cmdid = completed[i]; |
1441 | 1434 | ||
1442 | if( cmdid == CMDID_INT_CMDS ) { /* internal command */ | 1435 | /* |
1436 | * Only free SCBs for the commands coming down from the | ||
1437 | * mid-layer, not for which were issued internally | ||
1438 | * | ||
1439 | * For internal command, restore the status returned by the | ||
1440 | * firmware so that user can interpret it. | ||
1441 | */ | ||
1442 | if (cmdid == CMDID_INT_CMDS) { | ||
1443 | scb = &adapter->int_scb; | 1443 | scb = &adapter->int_scb; |
1444 | cmd = scb->cmd; | ||
1445 | mbox = (mbox_t *)scb->raw_mbox; | ||
1446 | 1444 | ||
1447 | /* | 1445 | list_del_init(&scb->list); |
1448 | * Internal command interface do not fire the extended | 1446 | scb->state = SCB_FREE; |
1449 | * passthru or 64-bit passthru | ||
1450 | */ | ||
1451 | pthru = scb->pthru; | ||
1452 | 1447 | ||
1453 | } | 1448 | adapter->int_status = status; |
1454 | else { | 1449 | complete(&adapter->int_waitq); |
1450 | } else { | ||
1455 | scb = &adapter->scb_list[cmdid]; | 1451 | scb = &adapter->scb_list[cmdid]; |
1456 | 1452 | ||
1457 | /* | 1453 | /* |
@@ -1640,25 +1636,7 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) | |||
1640 | cmd->result |= (DID_BAD_TARGET << 16)|status; | 1636 | cmd->result |= (DID_BAD_TARGET << 16)|status; |
1641 | } | 1637 | } |
1642 | 1638 | ||
1643 | /* | 1639 | mega_free_scb(adapter, scb); |
1644 | * Only free SCBs for the commands coming down from the | ||
1645 | * mid-layer, not for which were issued internally | ||
1646 | * | ||
1647 | * For internal command, restore the status returned by the | ||
1648 | * firmware so that user can interpret it. | ||
1649 | */ | ||
1650 | if( cmdid == CMDID_INT_CMDS ) { /* internal command */ | ||
1651 | cmd->result = status; | ||
1652 | |||
1653 | /* | ||
1654 | * Remove the internal command from the pending list | ||
1655 | */ | ||
1656 | list_del_init(&scb->list); | ||
1657 | scb->state = SCB_FREE; | ||
1658 | } | ||
1659 | else { | ||
1660 | mega_free_scb(adapter, scb); | ||
1661 | } | ||
1662 | 1640 | ||
1663 | /* Add Scsi_Command to end of completed queue */ | 1641 | /* Add Scsi_Command to end of completed queue */ |
1664 | list_add_tail(SCSI_LIST(cmd), &adapter->completed_list); | 1642 | list_add_tail(SCSI_LIST(cmd), &adapter->completed_list); |
@@ -4133,23 +4111,15 @@ mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt, | |||
4133 | * The last argument is the address of the passthru structure if the command | 4111 | * The last argument is the address of the passthru structure if the command |
4134 | * to be fired is a passthru command | 4112 | * to be fired is a passthru command |
4135 | * | 4113 | * |
4136 | * lockscope specifies whether the caller has already acquired the lock. Of | ||
4137 | * course, the caller must know which lock we are talking about. | ||
4138 | * | ||
4139 | * Note: parameter 'pthru' is null for non-passthru commands. | 4114 | * Note: parameter 'pthru' is null for non-passthru commands. |
4140 | */ | 4115 | */ |
4141 | static int | 4116 | static int |
4142 | mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | 4117 | mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) |
4143 | { | 4118 | { |
4144 | Scsi_Cmnd *scmd; | 4119 | unsigned long flags; |
4145 | struct scsi_device *sdev; | ||
4146 | scb_t *scb; | 4120 | scb_t *scb; |
4147 | int rval; | 4121 | int rval; |
4148 | 4122 | ||
4149 | scmd = scsi_allocate_command(GFP_KERNEL); | ||
4150 | if (!scmd) | ||
4151 | return -ENOMEM; | ||
4152 | |||
4153 | /* | 4123 | /* |
4154 | * The internal commands share one command id and hence are | 4124 | * The internal commands share one command id and hence are |
4155 | * serialized. This is so because we want to reserve maximum number of | 4125 | * serialized. This is so because we want to reserve maximum number of |
@@ -4160,73 +4130,45 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | |||
4160 | scb = &adapter->int_scb; | 4130 | scb = &adapter->int_scb; |
4161 | memset(scb, 0, sizeof(scb_t)); | 4131 | memset(scb, 0, sizeof(scb_t)); |
4162 | 4132 | ||
4163 | sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); | 4133 | scb->idx = CMDID_INT_CMDS; |
4164 | scmd->device = sdev; | 4134 | scb->state |= SCB_ACTIVE | SCB_PENDQ; |
4165 | |||
4166 | memset(adapter->int_cdb, 0, sizeof(adapter->int_cdb)); | ||
4167 | scmd->cmnd = adapter->int_cdb; | ||
4168 | scmd->device->host = adapter->host; | ||
4169 | scmd->host_scribble = (void *)scb; | ||
4170 | scmd->cmnd[0] = MEGA_INTERNAL_CMD; | ||
4171 | |||
4172 | scb->state |= SCB_ACTIVE; | ||
4173 | scb->cmd = scmd; | ||
4174 | 4135 | ||
4175 | memcpy(scb->raw_mbox, mc, sizeof(megacmd_t)); | 4136 | memcpy(scb->raw_mbox, mc, sizeof(megacmd_t)); |
4176 | 4137 | ||
4177 | /* | 4138 | /* |
4178 | * Is it a passthru command | 4139 | * Is it a passthru command |
4179 | */ | 4140 | */ |
4180 | if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) { | 4141 | if (mc->cmd == MEGA_MBOXCMD_PASSTHRU) |
4181 | |||
4182 | scb->pthru = pthru; | 4142 | scb->pthru = pthru; |
4183 | } | ||
4184 | |||
4185 | scb->idx = CMDID_INT_CMDS; | ||
4186 | 4143 | ||
4187 | megaraid_queue_lck(scmd, mega_internal_done); | 4144 | spin_lock_irqsave(&adapter->lock, flags); |
4145 | list_add_tail(&scb->list, &adapter->pending_list); | ||
4146 | /* | ||
4147 | * Check if the HBA is in quiescent state, e.g., during a | ||
4148 | * delete logical drive opertion. If it is, don't run | ||
4149 | * the pending_list. | ||
4150 | */ | ||
4151 | if (atomic_read(&adapter->quiescent) == 0) | ||
4152 | mega_runpendq(adapter); | ||
4153 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
4188 | 4154 | ||
4189 | wait_for_completion(&adapter->int_waitq); | 4155 | wait_for_completion(&adapter->int_waitq); |
4190 | 4156 | ||
4191 | rval = scmd->result; | 4157 | mc->status = rval = adapter->int_status; |
4192 | mc->status = scmd->result; | ||
4193 | kfree(sdev); | ||
4194 | 4158 | ||
4195 | /* | 4159 | /* |
4196 | * Print a debug message for all failed commands. Applications can use | 4160 | * Print a debug message for all failed commands. Applications can use |
4197 | * this information. | 4161 | * this information. |
4198 | */ | 4162 | */ |
4199 | if( scmd->result && trace_level ) { | 4163 | if (rval && trace_level) { |
4200 | printk("megaraid: cmd [%x, %x, %x] status:[%x]\n", | 4164 | printk("megaraid: cmd [%x, %x, %x] status:[%x]\n", |
4201 | mc->cmd, mc->opcode, mc->subopcode, scmd->result); | 4165 | mc->cmd, mc->opcode, mc->subopcode, rval); |
4202 | } | 4166 | } |
4203 | 4167 | ||
4204 | mutex_unlock(&adapter->int_mtx); | 4168 | mutex_unlock(&adapter->int_mtx); |
4205 | |||
4206 | scsi_free_command(GFP_KERNEL, scmd); | ||
4207 | |||
4208 | return rval; | 4169 | return rval; |
4209 | } | 4170 | } |
4210 | 4171 | ||
4211 | |||
4212 | /** | ||
4213 | * mega_internal_done() | ||
4214 | * @scmd - internal scsi command | ||
4215 | * | ||
4216 | * Callback routine for internal commands. | ||
4217 | */ | ||
4218 | static void | ||
4219 | mega_internal_done(Scsi_Cmnd *scmd) | ||
4220 | { | ||
4221 | adapter_t *adapter; | ||
4222 | |||
4223 | adapter = (adapter_t *)scmd->device->host->hostdata; | ||
4224 | |||
4225 | complete(&adapter->int_waitq); | ||
4226 | |||
4227 | } | ||
4228 | |||
4229 | |||
4230 | static struct scsi_host_template megaraid_template = { | 4172 | static struct scsi_host_template megaraid_template = { |
4231 | .module = THIS_MODULE, | 4173 | .module = THIS_MODULE, |
4232 | .name = "MegaRAID", | 4174 | .name = "MegaRAID", |