From b21227c5fcadab206e2a2373e5b288a351919abb Mon Sep 17 00:00:00 2001 From: "Hillier, Gernot" Date: Wed, 17 Sep 2008 16:03:06 +0200 Subject: [PATCH 1/5] [SCSI] aacraid: disable Dell Percraid quirk on Adaptec 2200S and 2120S A lot of 64bit machines with Adaptec 2200S and 2120S controllers don't recognize SCSI disks any more with the patch commit 94cf6ba11b068b8a8f68a1e88bffb6827e92124b Author: Salyzyn, Mark Date: Thu Dec 13 16:14:18 2007 -0800 [SCSI] aacraid: fix driver failure with Dell PowerEdge Expandable RAID Controller 3/Di but fail with tons of "aac_srb: aac_fib_send failed with status: 8195" instead. This patch disables the quirk introduced in the change cited above for those two controllers again. [thenzl: added 2120S Controller] Signed-off-by: Gernot Hillier Signed-off-by: Tomas Henzl Acked-by: Matt Domsch Cc: AACRAID list Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/aacraid/linit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 162cd927d94b..94acbeed4e7c 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -175,8 +175,8 @@ static struct aac_driver_ident aac_drivers[] = { { aac_rx_init, "percraid", "DELL ", "PERCRAID ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* PERC 3/Di (Boxster/PERC3DiB) */ { aac_rx_init, "aacraid", "ADAPTEC ", "catapult ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* catapult */ { aac_rx_init, "aacraid", "ADAPTEC ", "tomcat ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* tomcat */ - { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2120S (Crusader) */ - { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2120S ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2120S (Crusader) */ + { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG }, /* Adaptec 2200S (Vulcan) */ { aac_rx_init, "aacraid", "ADAPTEC ", "Adaptec 2200S ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Adaptec 2200S (Vulcan-2m) */ { aac_rx_init, "aacraid", "Legend ", "Legend S220 ", 1, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S220 (Legend Crusader) */ { aac_rx_init, "aacraid", "Legend ", "Legend S230 ", 2, AAC_QUIRK_31BIT | AAC_QUIRK_34SG | AAC_QUIRK_SCSI_32 }, /* Legend S230 (Legend Vulcan) */ From d3acf0226debeae22d87808f8f298386bd08e391 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 1 Dec 2008 12:13:00 -0600 Subject: [PATCH 2/5] [SCSI] libiscsi REGRESSION: fix passthrough support with older iscsi tools This regression was added in 2.6.27, when the mtask and ctask were merged into the the common task struct. The patch applies to scsi-rc-fixes, but also applies to 2.6.27 with some offsets. The problem is that __iscsi_conn_send_pdu assumes that userspace was not sending nops with the format it is checking for in the "if" below. It turns out that older userspace tools are. This patch moves the setting of the internal ping_task tracker (it tracks libiscsi current outstanding nop) to iscsi_send_nopout which is only used by kernel callers. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 801c7cf54d2e..3fdee7370ccc 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -489,12 +489,6 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (!__kfifo_get(session->cmdpool.queue, (void*)&task, sizeof(void*))) return NULL; - - if ((hdr->opcode == (ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE)) && - hdr->ttt == RESERVED_ITT) { - conn->ping_task = task; - conn->last_ping = jiffies; - } } /* * released in complete pdu for task we expect a response for, and @@ -703,6 +697,11 @@ static void iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0); if (!task) iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n"); + else if (!rhdr) { + /* only track our nops */ + conn->ping_task = task; + conn->last_ping = jiffies; + } } static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, From 57458036af75c6dbb62bee04b3982e92261eddb1 Mon Sep 17 00:00:00 2001 From: Brian King Date: Tue, 9 Dec 2008 20:03:50 +0900 Subject: [PATCH 3/5] [SCSI] ibmvstgt: move crq_queue_create to the end of initialization Calling crq_queue_create could lead to the creation of a rport. We need to set up everything before creating a rport. This moves crq_queue_create to the end of initialization to avoid a race which causes an oops if lost. Signed-off-by: Brian King Signed-off-by: FUJITA Tomonori Reported-by: Olaf Hering Cc: stable@kernel.org Signed-off-by: James Bottomley --- drivers/scsi/ibmvscsi/ibmvstgt.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 2a5b29d12172..e2dd6a45924a 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -864,21 +864,23 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) INIT_WORK(&vport->crq_work, handle_crq); - err = crq_queue_create(&vport->crq_queue, target); + err = scsi_add_host(shost, target->dev); if (err) goto free_srp_target; - err = scsi_add_host(shost, target->dev); - if (err) - goto destroy_queue; - err = scsi_tgt_alloc_queue(shost); if (err) - goto destroy_queue; + goto remove_host; + + err = crq_queue_create(&vport->crq_queue, target); + if (err) + goto free_queue; return 0; -destroy_queue: - crq_queue_destroy(target); +free_queue: + scsi_tgt_free_queue(shost); +remove_host: + scsi_remove_host(shost); free_srp_target: srp_target_free(target); put_host: From 02bd3499a3be984f1e88821c3ed252c8c49c498e Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 12 Dec 2008 13:28:29 -0600 Subject: [PATCH 4/5] [SCSI] scsi_lib: only call scsi_unprep_request() under queue lock It's called under that lock everywhere else and it does alter the request state, so it should be. This one occurance in scsi_requeue_command() could open a window where req->special is set to NULL while the requests is going through either timeout or completion processing leading to NULL pointer derefs of the sort complained of in bugzillas 12020 and 12195. Signed-off-by: James Bottomley --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index fa45a1a66867..148d3af92aef 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -648,8 +648,8 @@ static void scsi_requeue_command(struct request_queue *q, struct scsi_cmnd *cmd) struct request *req = cmd->request; unsigned long flags; - scsi_unprep_request(req); spin_lock_irqsave(q->queue_lock, flags); + scsi_unprep_request(req); blk_requeue_request(q, req); spin_unlock_irqrestore(q->queue_lock, flags); From a6da74cb077e88a604e5b2a6663b44c221f0ae75 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 15 Dec 2008 14:13:27 -0600 Subject: [PATCH 5/5] [SCSI] mpt fusion: clear list of outstanding commands on host reset A bug in the fusion driver was exposed by the switch to block timeout. Basically, drivers are supposed to terminate commands once error handling begins on them. The fusion apparently wasn't doing this. Under the old timeout regime, completions on terminated commands would by and large get ignored because of the way command timeouts used to work. The new block timers are very intolerant to this, though, becuase the request gets cleaned and freed. Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=12195 Reported-by: Alex Shi Tested-by: Ming Lin Cc: Eric Moore Signed-off-by: James Bottomley --- drivers/message/fusion/mptscsih.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index d62fd4f6b52e..ee090413e598 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -2008,6 +2008,9 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt) return FAILED; } + /* make sure we have no outstanding commands at this stage */ + mptscsih_flush_running_cmds(hd); + ioc = hd->ioc; printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n", ioc->name, SCpnt);