diff options
Diffstat (limited to 'drivers/scsi/dc395x.c')
-rw-r--r-- | drivers/scsi/dc395x.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 0c56095f8140..183245254931 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c | |||
@@ -3347,21 +3347,14 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3347 | { | 3347 | { |
3348 | u8 tempcnt, status; | 3348 | u8 tempcnt, status; |
3349 | struct scsi_cmnd *cmd = srb->cmd; | 3349 | struct scsi_cmnd *cmd = srb->cmd; |
3350 | struct ScsiInqData *ptr; | ||
3351 | enum dma_data_direction dir = cmd->sc_data_direction; | 3350 | enum dma_data_direction dir = cmd->sc_data_direction; |
3352 | 3351 | int ckc_only = 1; | |
3353 | if (cmd->use_sg) { | ||
3354 | struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; | ||
3355 | ptr = (struct ScsiInqData *)(page_address(sg->page) + sg->offset); | ||
3356 | } else { | ||
3357 | ptr = (struct ScsiInqData *)(cmd->request_buffer); | ||
3358 | } | ||
3359 | 3352 | ||
3360 | dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, | 3353 | dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, |
3361 | srb->cmd->device->id, srb->cmd->device->lun); | 3354 | srb->cmd->device->id, srb->cmd->device->lun); |
3362 | dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p addr=%p\n", | 3355 | dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", |
3363 | srb, cmd->use_sg, srb->sg_index, srb->sg_count, | 3356 | srb, cmd->use_sg, srb->sg_index, srb->sg_count, |
3364 | cmd->request_buffer, ptr); | 3357 | cmd->request_buffer); |
3365 | status = srb->target_status; | 3358 | status = srb->target_status; |
3366 | if (srb->flag & AUTO_REQSENSE) { | 3359 | if (srb->flag & AUTO_REQSENSE) { |
3367 | dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n"); | 3360 | dprintkdbg(DBG_0, "srb_done: AUTO_REQSENSE1\n"); |
@@ -3500,29 +3493,47 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3500 | srb->segment_x[0].address, | 3493 | srb->segment_x[0].address, |
3501 | cmd->request_bufflen, dir); | 3494 | cmd->request_bufflen, dir); |
3502 | } | 3495 | } |
3503 | 3496 | ckc_only = 0; | |
3504 | if ((cmd->result & RES_DID) == 0 && cmd->cmnd[0] == INQUIRY | ||
3505 | && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8 | ||
3506 | && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2) | ||
3507 | dcb->inquiry7 = ptr->Flags; | ||
3508 | /* Check Error Conditions */ | 3497 | /* Check Error Conditions */ |
3509 | ckc_e: | 3498 | ckc_e: |
3510 | 3499 | ||
3500 | if (cmd->cmnd[0] == INQUIRY) { | ||
3501 | unsigned char *base = NULL; | ||
3502 | struct ScsiInqData *ptr; | ||
3503 | unsigned long flags = 0; | ||
3504 | |||
3505 | if (cmd->use_sg) { | ||
3506 | struct scatterlist* sg = (struct scatterlist *)cmd->request_buffer; | ||
3507 | size_t offset = 0, len = sizeof(struct ScsiInqData); | ||
3508 | |||
3509 | local_irq_save(flags); | ||
3510 | base = scsi_kmap_atomic_sg(sg, cmd->use_sg, &offset, &len); | ||
3511 | ptr = (struct ScsiInqData *)(base + offset); | ||
3512 | } else | ||
3513 | ptr = (struct ScsiInqData *)(cmd->request_buffer); | ||
3514 | |||
3515 | if (!ckc_only && (cmd->result & RES_DID) == 0 | ||
3516 | && cmd->cmnd[2] == 0 && cmd->request_bufflen >= 8 | ||
3517 | && dir != PCI_DMA_NONE && ptr && (ptr->Vers & 0x07) >= 2) | ||
3518 | dcb->inquiry7 = ptr->Flags; | ||
3519 | |||
3511 | /*if( srb->cmd->cmnd[0] == INQUIRY && */ | 3520 | /*if( srb->cmd->cmnd[0] == INQUIRY && */ |
3512 | /* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */ | 3521 | /* (host_byte(cmd->result) == DID_OK || status_byte(cmd->result) & CHECK_CONDITION) ) */ |
3513 | if (cmd->cmnd[0] == INQUIRY && (cmd->result == (DID_OK << 16) | 3522 | if ((cmd->result == (DID_OK << 16) |
3514 | || status_byte(cmd-> | 3523 | || status_byte(cmd->result) & |
3515 | result) & | 3524 | CHECK_CONDITION)) { |
3516 | CHECK_CONDITION)) { | 3525 | if (!dcb->init_tcq_flag) { |
3517 | 3526 | add_dev(acb, dcb, ptr); | |
3518 | if (!dcb->init_tcq_flag) { | 3527 | dcb->init_tcq_flag = 1; |
3519 | add_dev(acb, dcb, ptr); | 3528 | } |
3520 | dcb->init_tcq_flag = 1; | ||
3521 | } | 3529 | } |
3522 | 3530 | ||
3531 | if (cmd->use_sg) { | ||
3532 | scsi_kunmap_atomic_sg(base); | ||
3533 | local_irq_restore(flags); | ||
3534 | } | ||
3523 | } | 3535 | } |
3524 | 3536 | ||
3525 | |||
3526 | /* Here is the info for Doug Gilbert's sg3 ... */ | 3537 | /* Here is the info for Doug Gilbert's sg3 ... */ |
3527 | cmd->resid = srb->total_xfer_length; | 3538 | cmd->resid = srb->total_xfer_length; |
3528 | /* This may be interpreted by sb. or not ... */ | 3539 | /* This may be interpreted by sb. or not ... */ |