aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikulas Patocka <mpatocka@redhat.com>2008-07-15 17:19:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-15 17:30:56 -0400
commit3a628b0fd42f7eaf9d052447784d48ceae9ffb8e (patch)
tree44ffc68125d966d58f7cf8a1905dc9b7143e57a8
parenta5db33411ae762e597bfcde6bb9d0c8c2ea9c0eb (diff)
Don't crash on IOMMU overflow in A100U2W driver
Handle IOMMU overflow correctly, by retrying. IOMMU errors can happen and drivers must deal with them. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/scsi/a100u2w.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index f5051f4301d7..84bb61628372 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -840,7 +840,7 @@ static irqreturn_t orc_interrupt(struct orc_host * host)
840 * Build a host adapter control block from the SCSI mid layer command 840 * Build a host adapter control block from the SCSI mid layer command
841 */ 841 */
842 842
843static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd) 843static int inia100_build_scb(struct orc_host * host, struct orc_scb * scb, struct scsi_cmnd * cmd)
844{ /* Create corresponding SCB */ 844{ /* Create corresponding SCB */
845 struct scatterlist *sg; 845 struct scatterlist *sg;
846 struct orc_sgent *sgent; /* Pointer to SG list */ 846 struct orc_sgent *sgent; /* Pointer to SG list */
@@ -865,7 +865,8 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
865 sgent = (struct orc_sgent *) & escb->sglist[0]; 865 sgent = (struct orc_sgent *) & escb->sglist[0];
866 866
867 count_sg = scsi_dma_map(cmd); 867 count_sg = scsi_dma_map(cmd);
868 BUG_ON(count_sg < 0); 868 if (count_sg < 0)
869 return count_sg;
869 BUG_ON(count_sg > TOTAL_SG_ENTRY); 870 BUG_ON(count_sg > TOTAL_SG_ENTRY);
870 871
871 /* Build the scatter gather lists */ 872 /* Build the scatter gather lists */
@@ -898,6 +899,7 @@ static void inia100_build_scb(struct orc_host * host, struct orc_scb * scb, stru
898 scb->tag_msg = 0; /* No tag support */ 899 scb->tag_msg = 0; /* No tag support */
899 } 900 }
900 memcpy(scb->cdb, cmd->cmnd, scb->cdb_len); 901 memcpy(scb->cdb, cmd->cmnd, scb->cdb_len);
902 return 0;
901} 903}
902 904
903/** 905/**
@@ -921,7 +923,10 @@ static int inia100_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd
921 if ((scb = orc_alloc_scb(host)) == NULL) 923 if ((scb = orc_alloc_scb(host)) == NULL)
922 return SCSI_MLQUEUE_HOST_BUSY; 924 return SCSI_MLQUEUE_HOST_BUSY;
923 925
924 inia100_build_scb(host, scb, cmd); 926 if (inia100_build_scb(host, scb, cmd)) {
927 orc_release_scb(host, scb);
928 return SCSI_MLQUEUE_HOST_BUSY;
929 }
925 orc_exec_scb(host, scb); /* Start execute SCB */ 930 orc_exec_scb(host, scb); /* Start execute SCB */
926 return 0; 931 return 0;
927} 932}