aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2009-07-02 16:02:06 -0400
committerJens Axboe <axboe@carl.(none)>2009-07-03 15:06:45 -0400
commitb59e64d0ddb756af57ea032383bfd393a286a8e8 (patch)
treeb3366a2a99e08021535eb841d1da0ac8a3e614e8
parentd960eea974f5e500c0dcb95a934239cc1f481cfd (diff)
cciss: Ignore stale commands after reboot
When doing an unexpected shutdown like kexec the cciss firmware might still have some commands in flight, which it is trying to complete. The driver is doing it's best on resetting the HBA, but sadly there's a firmware issue causing the firmware _not_ to abort or drop old commands. So the firmware will send us commands which we haven't accounted for, causing the driver to panic. With this patch we're just ignoring these commands as there is nothing we could be doing with them anyway. Signed-off-by: Hannes Reinecke <hare@suse.de> Acked-by: Mike Miller <mike.miller@hp.com> Signed-off-by: Jens Axboe <axboe@carl.(none)>
-rw-r--r--drivers/block/cciss.c15
-rw-r--r--drivers/block/cciss_cmd.h1
2 files changed, 14 insertions, 2 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index c7a527c08a09..65a0655e7fc8 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -226,8 +226,18 @@ static inline void addQ(struct hlist_head *list, CommandList_struct *c)
226 226
227static inline void removeQ(CommandList_struct *c) 227static inline void removeQ(CommandList_struct *c)
228{ 228{
229 if (WARN_ON(hlist_unhashed(&c->list))) 229 /*
230 * After kexec/dump some commands might still
231 * be in flight, which the firmware will try
232 * to complete. Resetting the firmware doesn't work
233 * with old fw revisions, so we have to mark
234 * them off as 'stale' to prevent the driver from
235 * falling over.
236 */
237 if (WARN_ON(hlist_unhashed(&c->list))) {
238 c->cmd_type = CMD_MSG_STALE;
230 return; 239 return;
240 }
231 241
232 hlist_del_init(&c->list); 242 hlist_del_init(&c->list);
233} 243}
@@ -4246,7 +4256,8 @@ static void fail_all_cmds(unsigned long ctlr)
4246 while (!hlist_empty(&h->cmpQ)) { 4256 while (!hlist_empty(&h->cmpQ)) {
4247 c = hlist_entry(h->cmpQ.first, CommandList_struct, list); 4257 c = hlist_entry(h->cmpQ.first, CommandList_struct, list);
4248 removeQ(c); 4258 removeQ(c);
4249 c->err_info->CommandStatus = CMD_HARDWARE_ERR; 4259 if (c->cmd_type != CMD_MSG_STALE)
4260 c->err_info->CommandStatus = CMD_HARDWARE_ERR;
4250 if (c->cmd_type == CMD_RWREQ) { 4261 if (c->cmd_type == CMD_RWREQ) {
4251 complete_command(h, c, 0); 4262 complete_command(h, c, 0);
4252 } else if (c->cmd_type == CMD_IOCTL_PEND) 4263 } else if (c->cmd_type == CMD_IOCTL_PEND)
diff --git a/drivers/block/cciss_cmd.h b/drivers/block/cciss_cmd.h
index cd665b00c7c5..dbaed1ea0da3 100644
--- a/drivers/block/cciss_cmd.h
+++ b/drivers/block/cciss_cmd.h
@@ -274,6 +274,7 @@ typedef struct _ErrorInfo_struct {
274#define CMD_SCSI 0x03 274#define CMD_SCSI 0x03
275#define CMD_MSG_DONE 0x04 275#define CMD_MSG_DONE 0x04
276#define CMD_MSG_TIMEOUT 0x05 276#define CMD_MSG_TIMEOUT 0x05
277#define CMD_MSG_STALE 0xff
277 278
278/* This structure needs to be divisible by 8 for new 279/* This structure needs to be divisible by 8 for new
279 * indexing method. 280 * indexing method.