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 | } |