From c95e62ce8905aab62fed224eaaa9b8558a0ef652 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 23 Jun 2008 09:14:31 -0600 Subject: [SCSI] ses: Fix timeout Timeouts are measured in jiffies, not in seconds. Signed-off-by: Matthew Wilcox Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/ses.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 45df83b9d847..0fe031f003e7 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -61,7 +61,7 @@ static int ses_probe(struct device *dev) return err; } -#define SES_TIMEOUT 30 +#define SES_TIMEOUT (30 * HZ) #define SES_RETRIES 3 static int ses_recv_diag(struct scsi_device *sdev, int page_code, -- cgit v1.2.3-59-g8ed1b From eadc49b1a8d09480f14caea292142f103a89c77a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 17 Jun 2008 23:53:22 -0700 Subject: [SCSI] esp: Fix OOPS in esp_reset_cleanup(). OOPS reported by Friedrich Oslage The problem here is that tp->starget is set every time a lun is allocated for a particular target so we can catch the sdev_target parent value. The reset handler uses the NULL'ness of this value to determine which targets are active. But esp_slave_destroy() does not NULL out this value when appropriate. So for every target that doesn't respond, the SCSI bus scan causes a stale pointer to be left here, with ensuing crashes like you're seeing. Signed-off-by: David S. Miller Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.c | 8 ++++++++ drivers/scsi/esp_scsi.h | 1 + 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index a0b6d414953d..305eddef5ca1 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2371,6 +2371,7 @@ static int esp_slave_alloc(struct scsi_device *dev) dev->hostdata = lp; tp->starget = dev->sdev_target; + tp->starget_ref++; spi_min_period(tp->starget) = esp->min_period; spi_max_offset(tp->starget) = 15; @@ -2425,10 +2426,17 @@ static int esp_slave_configure(struct scsi_device *dev) static void esp_slave_destroy(struct scsi_device *dev) { + struct esp *esp = shost_priv(dev->host); + struct esp_target_data *tp = &esp->target[dev->id]; struct esp_lun_data *lp = dev->hostdata; kfree(lp); dev->hostdata = NULL; + + BUG_ON(tp->starget_ref <= 0); + + if (!--tp->starget_ref) + tp->starget = NULL; } static int esp_eh_abort_handler(struct scsi_cmnd *cmd) diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index bb43a1388188..655e0b2240bf 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -322,6 +322,7 @@ struct esp_target_data { u8 nego_goal_tags; struct scsi_target *starget; + int starget_ref; }; struct esp_event_ent { -- cgit v1.2.3-59-g8ed1b From ec5e69f6d3f4350681d6f7eaae515cf014be9276 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Mon, 23 Jun 2008 14:52:09 -0500 Subject: [SCSI] esp: tidy up target reference counting The esp driver currently does hand rolled reference counting of its target. It's much easier to do what it needs to do if it's plugged into the mid-layer callbacks (target_alloc and target_destroy) which were designed for this case, so do it this way and get rid of the internal target reference count. Acked-by: David S. Miller Cc: Stable Tree Signed-off-by: James Bottomley --- drivers/scsi/esp_scsi.c | 30 ++++++++++++++++++++---------- drivers/scsi/esp_scsi.h | 1 - 2 files changed, 20 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 305eddef5ca1..59fbef08d690 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2359,6 +2359,24 @@ void scsi_esp_unregister(struct esp *esp) } EXPORT_SYMBOL(scsi_esp_unregister); +static int esp_target_alloc(struct scsi_target *starget) +{ + struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); + struct esp_target_data *tp = &esp->target[starget->id]; + + tp->starget = starget; + + return 0; +} + +static void esp_target_destroy(struct scsi_target *starget) +{ + struct esp *esp = shost_priv(dev_to_shost(&starget->dev)); + struct esp_target_data *tp = &esp->target[starget->id]; + + tp->starget = NULL; +} + static int esp_slave_alloc(struct scsi_device *dev) { struct esp *esp = shost_priv(dev->host); @@ -2370,9 +2388,6 @@ static int esp_slave_alloc(struct scsi_device *dev) return -ENOMEM; dev->hostdata = lp; - tp->starget = dev->sdev_target; - tp->starget_ref++; - spi_min_period(tp->starget) = esp->min_period; spi_max_offset(tp->starget) = 15; @@ -2426,17 +2441,10 @@ static int esp_slave_configure(struct scsi_device *dev) static void esp_slave_destroy(struct scsi_device *dev) { - struct esp *esp = shost_priv(dev->host); - struct esp_target_data *tp = &esp->target[dev->id]; struct esp_lun_data *lp = dev->hostdata; kfree(lp); dev->hostdata = NULL; - - BUG_ON(tp->starget_ref <= 0); - - if (!--tp->starget_ref) - tp->starget = NULL; } static int esp_eh_abort_handler(struct scsi_cmnd *cmd) @@ -2616,6 +2624,8 @@ struct scsi_host_template scsi_esp_template = { .name = "esp", .info = esp_info, .queuecommand = esp_queuecommand, + .target_alloc = esp_target_alloc, + .target_destroy = esp_target_destroy, .slave_alloc = esp_slave_alloc, .slave_configure = esp_slave_configure, .slave_destroy = esp_slave_destroy, diff --git a/drivers/scsi/esp_scsi.h b/drivers/scsi/esp_scsi.h index 655e0b2240bf..bb43a1388188 100644 --- a/drivers/scsi/esp_scsi.h +++ b/drivers/scsi/esp_scsi.h @@ -322,7 +322,6 @@ struct esp_target_data { u8 nego_goal_tags; struct scsi_target *starget; - int starget_ref; }; struct esp_event_ent { -- cgit v1.2.3-59-g8ed1b