diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-09 21:35:53 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-09 21:35:53 -0400 |
| commit | 93cb463141d50e4c6a574efc2c6e4d6d76ffed77 (patch) | |
| tree | 3d15e3ba65a28bc2df08f388acaa02f1f4f09cce | |
| parent | 1c6fe0364fa7bf28248488753ee0afb6b759cd04 (diff) | |
| parent | 77a4229719e511a0d38d9c355317ae1469adeb54 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6:
[SCSI] Retry commands with UNIT_ATTENTION sense codes to fix ext3/ext4 I/O error
[SCSI] Enable retries for SYNCRONIZE_CACHE commands to fix I/O error
[SCSI] scsi_debug: virtual_gb ignores sector_size
[SCSI] libiscsi: regression: fix header digest errors
[SCSI] fix locking around blk_abort_request()
[SCSI] advansys: fix narrow board error path
| -rw-r--r-- | drivers/scsi/advansys.c | 50 | ||||
| -rw-r--r-- | drivers/scsi/libiscsi.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/scsi_debug.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/scsi_error.c | 15 | ||||
| -rw-r--r-- | drivers/scsi/sd.c | 1 |
7 files changed, 62 insertions, 17 deletions
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 9201afe65609..7f87979da22d 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
| @@ -4724,6 +4724,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
| 4724 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); | 4724 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); |
| 4725 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, | 4725 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, |
| 4726 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | 4726 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); |
| 4727 | if (dma_mapping_error(board->dev, asc_dvc->overrun_dma)) { | ||
| 4728 | warn_code = -ENOMEM; | ||
| 4729 | goto err_dma_map; | ||
| 4730 | } | ||
| 4727 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); | 4731 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); |
| 4728 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | 4732 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, |
| 4729 | (uchar *)&phy_addr, 1); | 4733 | (uchar *)&phy_addr, 1); |
| @@ -4739,14 +4743,23 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | |||
| 4739 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | 4743 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); |
| 4740 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | 4744 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { |
| 4741 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | 4745 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; |
| 4742 | return warn_code; | 4746 | warn_code = UW_ERR; |
| 4747 | goto err_mcode_start; | ||
| 4743 | } | 4748 | } |
| 4744 | if (AscStartChip(iop_base) != 1) { | 4749 | if (AscStartChip(iop_base) != 1) { |
| 4745 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | 4750 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; |
| 4746 | return warn_code; | 4751 | warn_code = UW_ERR; |
| 4752 | goto err_mcode_start; | ||
| 4747 | } | 4753 | } |
| 4748 | 4754 | ||
| 4749 | return warn_code; | 4755 | return warn_code; |
| 4756 | |||
| 4757 | err_mcode_start: | ||
| 4758 | dma_unmap_single(board->dev, asc_dvc->overrun_dma, | ||
| 4759 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
| 4760 | err_dma_map: | ||
| 4761 | asc_dvc->overrun_dma = 0; | ||
| 4762 | return warn_code; | ||
| 4750 | } | 4763 | } |
| 4751 | 4764 | ||
| 4752 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | 4765 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) |
| @@ -4802,6 +4815,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | |||
| 4802 | } | 4815 | } |
| 4803 | release_firmware(fw); | 4816 | release_firmware(fw); |
| 4804 | warn_code |= AscInitMicroCodeVar(asc_dvc); | 4817 | warn_code |= AscInitMicroCodeVar(asc_dvc); |
| 4818 | if (!asc_dvc->overrun_dma) | ||
| 4819 | return warn_code; | ||
| 4805 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; | 4820 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; |
| 4806 | AscEnableInterrupt(iop_base); | 4821 | AscEnableInterrupt(iop_base); |
| 4807 | return warn_code; | 4822 | return warn_code; |
| @@ -7978,9 +7993,10 @@ static int advansys_reset(struct scsi_cmnd *scp) | |||
| 7978 | status = AscInitAsc1000Driver(asc_dvc); | 7993 | status = AscInitAsc1000Driver(asc_dvc); |
| 7979 | 7994 | ||
| 7980 | /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */ | 7995 | /* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */ |
| 7981 | if (asc_dvc->err_code) { | 7996 | if (asc_dvc->err_code || !asc_dvc->overrun_dma) { |
| 7982 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " | 7997 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " |
| 7983 | "0x%x\n", asc_dvc->err_code); | 7998 | "0x%x, status: 0x%x\n", asc_dvc->err_code, |
| 7999 | status); | ||
| 7984 | ret = FAILED; | 8000 | ret = FAILED; |
| 7985 | } else if (status) { | 8001 | } else if (status) { |
| 7986 | scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " | 8002 | scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " |
| @@ -12311,7 +12327,7 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
| 12311 | asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); | 12327 | asc_dvc_varp->overrun_buf = kzalloc(ASC_OVERRUN_BSIZE, GFP_KERNEL); |
| 12312 | if (!asc_dvc_varp->overrun_buf) { | 12328 | if (!asc_dvc_varp->overrun_buf) { |
| 12313 | ret = -ENOMEM; | 12329 | ret = -ENOMEM; |
| 12314 | goto err_free_wide_mem; | 12330 | goto err_free_irq; |
| 12315 | } | 12331 | } |
| 12316 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); | 12332 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); |
| 12317 | 12333 | ||
| @@ -12320,30 +12336,36 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost, | |||
| 12320 | "warn 0x%x, error 0x%x\n", | 12336 | "warn 0x%x, error 0x%x\n", |
| 12321 | asc_dvc_varp->init_state, warn_code, | 12337 | asc_dvc_varp->init_state, warn_code, |
| 12322 | asc_dvc_varp->err_code); | 12338 | asc_dvc_varp->err_code); |
| 12323 | if (asc_dvc_varp->err_code) { | 12339 | if (!asc_dvc_varp->overrun_dma) { |
| 12324 | ret = -ENODEV; | 12340 | ret = -ENODEV; |
| 12325 | kfree(asc_dvc_varp->overrun_buf); | 12341 | goto err_free_mem; |
| 12326 | } | 12342 | } |
| 12327 | } | 12343 | } |
| 12328 | } else { | 12344 | } else { |
| 12329 | if (advansys_wide_init_chip(shost)) | 12345 | if (advansys_wide_init_chip(shost)) { |
| 12330 | ret = -ENODEV; | 12346 | ret = -ENODEV; |
| 12347 | goto err_free_mem; | ||
| 12348 | } | ||
| 12331 | } | 12349 | } |
| 12332 | 12350 | ||
| 12333 | if (ret) | ||
| 12334 | goto err_free_wide_mem; | ||
| 12335 | |||
| 12336 | ASC_DBG_PRT_SCSI_HOST(2, shost); | 12351 | ASC_DBG_PRT_SCSI_HOST(2, shost); |
| 12337 | 12352 | ||
| 12338 | ret = scsi_add_host(shost, boardp->dev); | 12353 | ret = scsi_add_host(shost, boardp->dev); |
| 12339 | if (ret) | 12354 | if (ret) |
| 12340 | goto err_free_wide_mem; | 12355 | goto err_free_mem; |
| 12341 | 12356 | ||
| 12342 | scsi_scan_host(shost); | 12357 | scsi_scan_host(shost); |
| 12343 | return 0; | 12358 | return 0; |
| 12344 | 12359 | ||
| 12345 | err_free_wide_mem: | 12360 | err_free_mem: |
| 12346 | advansys_wide_free_mem(boardp); | 12361 | if (ASC_NARROW_BOARD(boardp)) { |
| 12362 | if (asc_dvc_varp->overrun_dma) | ||
| 12363 | dma_unmap_single(boardp->dev, asc_dvc_varp->overrun_dma, | ||
| 12364 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
| 12365 | kfree(asc_dvc_varp->overrun_buf); | ||
| 12366 | } else | ||
| 12367 | advansys_wide_free_mem(boardp); | ||
| 12368 | err_free_irq: | ||
| 12347 | free_irq(boardp->irq, shost); | 12369 | free_irq(boardp->irq, shost); |
| 12348 | err_free_dma: | 12370 | err_free_dma: |
| 12349 | #ifdef CONFIG_ISA | 12371 | #ifdef CONFIG_ISA |
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 6d5ae4474bb3..633e09036357 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -471,12 +471,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) | |||
| 471 | 471 | ||
| 472 | WARN_ON(hdrlength >= 256); | 472 | WARN_ON(hdrlength >= 256); |
| 473 | hdr->hlength = hdrlength & 0xFF; | 473 | hdr->hlength = hdrlength & 0xFF; |
| 474 | hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn); | ||
| 474 | 475 | ||
| 475 | if (session->tt->init_task && session->tt->init_task(task)) | 476 | if (session->tt->init_task && session->tt->init_task(task)) |
| 476 | return -EIO; | 477 | return -EIO; |
| 477 | 478 | ||
| 478 | task->state = ISCSI_TASK_RUNNING; | 479 | task->state = ISCSI_TASK_RUNNING; |
| 479 | hdr->cmdsn = task->cmdsn = cpu_to_be32(session->cmdsn); | ||
| 480 | session->cmdsn++; | 480 | session->cmdsn++; |
| 481 | 481 | ||
| 482 | conn->scsicmd_pdus_cnt++; | 482 | conn->scsicmd_pdus_cnt++; |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index b00efd19aadb..88f744672576 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
| @@ -395,11 +395,15 @@ int sas_ata_init_host_and_port(struct domain_device *found_dev, | |||
| 395 | void sas_ata_task_abort(struct sas_task *task) | 395 | void sas_ata_task_abort(struct sas_task *task) |
| 396 | { | 396 | { |
| 397 | struct ata_queued_cmd *qc = task->uldd_task; | 397 | struct ata_queued_cmd *qc = task->uldd_task; |
| 398 | struct request_queue *q = qc->scsicmd->device->request_queue; | ||
| 398 | struct completion *waiting; | 399 | struct completion *waiting; |
| 400 | unsigned long flags; | ||
| 399 | 401 | ||
| 400 | /* Bounce SCSI-initiated commands to the SCSI EH */ | 402 | /* Bounce SCSI-initiated commands to the SCSI EH */ |
| 401 | if (qc->scsicmd) { | 403 | if (qc->scsicmd) { |
| 404 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 402 | blk_abort_request(qc->scsicmd->request); | 405 | blk_abort_request(qc->scsicmd->request); |
| 406 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 403 | scsi_schedule_eh(qc->scsicmd->device->host); | 407 | scsi_schedule_eh(qc->scsicmd->device->host); |
| 404 | return; | 408 | return; |
| 405 | } | 409 | } |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 2660e1b4569a..822835055cef 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
| @@ -1030,6 +1030,8 @@ int __sas_task_abort(struct sas_task *task) | |||
| 1030 | void sas_task_abort(struct sas_task *task) | 1030 | void sas_task_abort(struct sas_task *task) |
| 1031 | { | 1031 | { |
| 1032 | struct scsi_cmnd *sc = task->uldd_task; | 1032 | struct scsi_cmnd *sc = task->uldd_task; |
| 1033 | struct request_queue *q = sc->device->request_queue; | ||
| 1034 | unsigned long flags; | ||
| 1033 | 1035 | ||
| 1034 | /* Escape for libsas internal commands */ | 1036 | /* Escape for libsas internal commands */ |
| 1035 | if (!sc) { | 1037 | if (!sc) { |
| @@ -1044,7 +1046,9 @@ void sas_task_abort(struct sas_task *task) | |||
| 1044 | return; | 1046 | return; |
| 1045 | } | 1047 | } |
| 1046 | 1048 | ||
| 1049 | spin_lock_irqsave(q->queue_lock, flags); | ||
| 1047 | blk_abort_request(sc->request); | 1050 | blk_abort_request(sc->request); |
| 1051 | spin_unlock_irqrestore(q->queue_lock, flags); | ||
| 1048 | scsi_schedule_eh(sc->device->host); | 1052 | scsi_schedule_eh(sc->device->host); |
| 1049 | } | 1053 | } |
| 1050 | 1054 | ||
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3e10c306de94..3a5bfd10b2cb 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
| @@ -957,7 +957,8 @@ static int resp_start_stop(struct scsi_cmnd * scp, | |||
| 957 | static sector_t get_sdebug_capacity(void) | 957 | static sector_t get_sdebug_capacity(void) |
| 958 | { | 958 | { |
| 959 | if (scsi_debug_virtual_gb > 0) | 959 | if (scsi_debug_virtual_gb > 0) |
| 960 | return 2048 * 1024 * (sector_t)scsi_debug_virtual_gb; | 960 | return (sector_t)scsi_debug_virtual_gb * |
| 961 | (1073741824 / scsi_debug_sector_size); | ||
| 961 | else | 962 | else |
| 962 | return sdebug_store_sectors; | 963 | return sdebug_store_sectors; |
| 963 | } | 964 | } |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index d45c69ca5737..7ad53fa42766 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -302,7 +302,20 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
| 302 | if (scmd->device->allow_restart && | 302 | if (scmd->device->allow_restart && |
| 303 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) | 303 | (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) |
| 304 | return FAILED; | 304 | return FAILED; |
| 305 | return SUCCESS; | 305 | |
| 306 | if (blk_barrier_rq(scmd->request)) | ||
| 307 | /* | ||
| 308 | * barrier requests should always retry on UA | ||
| 309 | * otherwise block will get a spurious error | ||
| 310 | */ | ||
| 311 | return NEEDS_RETRY; | ||
| 312 | else | ||
| 313 | /* | ||
| 314 | * for normal (non barrier) commands, pass the | ||
| 315 | * UA upwards for a determination in the | ||
| 316 | * completion functions | ||
| 317 | */ | ||
| 318 | return SUCCESS; | ||
| 306 | 319 | ||
| 307 | /* these three are not supported */ | 320 | /* these three are not supported */ |
| 308 | case COPY_ABORTED: | 321 | case COPY_ABORTED: |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8b827f37b03e..de6c60320f6f 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
| @@ -1040,6 +1040,7 @@ static void sd_prepare_flush(struct request_queue *q, struct request *rq) | |||
| 1040 | { | 1040 | { |
| 1041 | rq->cmd_type = REQ_TYPE_BLOCK_PC; | 1041 | rq->cmd_type = REQ_TYPE_BLOCK_PC; |
| 1042 | rq->timeout = SD_TIMEOUT; | 1042 | rq->timeout = SD_TIMEOUT; |
| 1043 | rq->retries = SD_MAX_RETRIES; | ||
| 1043 | rq->cmd[0] = SYNCHRONIZE_CACHE; | 1044 | rq->cmd[0] = SYNCHRONIZE_CACHE; |
| 1044 | rq->cmd_len = 10; | 1045 | rq->cmd_len = 10; |
| 1045 | } | 1046 | } |
