Commit 4e665bdd authored by James Bottomley's avatar James Bottomley

fix NC5380 locking and delayed work handling

From: Christoph Hellwig <hch@lst.de>

 - move delayed workqueue handling to schedule_delayed_work instead
   of the old horrible global list thing
 - add NCR5380_exit to make sure all delayed work is flushed on HBA
   (or module) removal
 - fix locking

Patch fixed up to apply and
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 8651e2bd
This diff is collapsed.
...@@ -251,7 +251,6 @@ ...@@ -251,7 +251,6 @@
struct NCR5380_hostdata { struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */ NCR5380_implementation_fields; /* implementation specific */
struct Scsi_Host *host; /* Host backpointer */ struct Scsi_Host *host; /* Host backpointer */
struct NCR5380_hostdata *next; /* Next in our hot chain */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */ unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected unsigned char targets_present; /* targets we have connected
to, so we can call a select to, so we can call a select
...@@ -270,7 +269,6 @@ struct NCR5380_hostdata { ...@@ -270,7 +269,6 @@ struct NCR5380_hostdata {
volatile unsigned aborted:1; /* flag, says aborted */ volatile unsigned aborted:1; /* flag, says aborted */
int flags; int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */ unsigned long time_expires; /* in jiffies, set prior to sleeping */
struct Scsi_Host *next_timer;
int select_time; /* timer in select for target response */ int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting; volatile Scsi_Cmnd *selecting;
struct work_struct coroutine; /* our co-routine */ struct work_struct coroutine; /* our co-routine */
...@@ -295,6 +293,7 @@ struct NCR5380_hostdata { ...@@ -295,6 +293,7 @@ struct NCR5380_hostdata {
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif #endif
static int NCR5380_init(struct Scsi_Host *instance, int flags); static int NCR5380_init(struct Scsi_Host *instance, int flags);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance); static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR #ifndef DONT_USE_INTR
static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs); static irqreturn_t NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
......
...@@ -321,6 +321,7 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec) ...@@ -321,6 +321,7 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
scsi_remove_host(host); scsi_remove_host(host);
free_irq(host->irq, host); free_irq(host->irq, host);
NCR5380_exit(host);
release_region(host->io_port, host->n_io_port); release_region(host->io_port, host->n_io_port);
scsi_host_put(host); scsi_host_put(host);
} }
......
...@@ -222,6 +222,7 @@ static void __exit ecoscsi_exit(void) ...@@ -222,6 +222,7 @@ static void __exit ecoscsi_exit(void)
if (shpnt->irq != IRQ_NONE) if (shpnt->irq != IRQ_NONE)
free_irq(shpnt->irq, NULL); free_irq(shpnt->irq, NULL);
NCR5380_exit(host);
if (shpnt->io_port) if (shpnt->io_port)
release_region(shpnt->io_port, shpnt->n_io_port); release_region(shpnt->io_port, shpnt->n_io_port);
......
...@@ -179,6 +179,7 @@ static void __devexit oakscsi_remove(struct expansion_card *ec) ...@@ -179,6 +179,7 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
ecard_set_drvdata(ec, NULL); ecard_set_drvdata(ec, NULL);
scsi_remove_host(host); scsi_remove_host(host);
NCR5380_exit(host);
release_region(host->io_port, host->n_io_port); release_region(host->io_port, host->n_io_port);
scsi_host_put(host); scsi_host_put(host);
} }
......
...@@ -106,9 +106,10 @@ static const char * dmx3191d_info(struct Scsi_Host *host) { ...@@ -106,9 +106,10 @@ static const char * dmx3191d_info(struct Scsi_Host *host) {
static int dmx3191d_release_resources(struct Scsi_Host *instance) static int dmx3191d_release_resources(struct Scsi_Host *instance)
{ {
release_region(instance->io_port, DMX3191D_REGION);
if(instance->irq!=SCSI_IRQ_NONE) if(instance->irq!=SCSI_IRQ_NONE)
free_irq(instance->irq, instance); free_irq(instance->irq, instance);
NCR5380_exit(instance);
release_region(instance->io_port, DMX3191D_REGION);
return 0; return 0;
} }
......
...@@ -451,6 +451,7 @@ static int dtc_release(struct Scsi_Host *shost) ...@@ -451,6 +451,7 @@ static int dtc_release(struct Scsi_Host *shost)
{ {
if (shost->irq) if (shost->irq)
free_irq(shost->irq, NULL); free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port) if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port); release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost); scsi_unregister(shost);
......
...@@ -502,14 +502,16 @@ int generic_NCR5380_release_resources(struct Scsi_Host *instance) ...@@ -502,14 +502,16 @@ int generic_NCR5380_release_resources(struct Scsi_Host *instance)
NCR5380_local_declare(); NCR5380_local_declare();
NCR5380_setup(instance); NCR5380_setup(instance);
if (instance->irq != SCSI_IRQ_NONE)
free_irq(instance->irq, NULL);
NCR5380_exit(instance);
#ifndef CONFIG_SCSI_G_NCR5380_MEM #ifndef CONFIG_SCSI_G_NCR5380_MEM
release_region(instance->NCR5380_instance_name, instance->n_io_port); release_region(instance->NCR5380_instance_name, instance->n_io_port);
#else #else
release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size); release_mem_region(instance->NCR5380_instance_name, NCR5380_region_size);
#endif #endif
if (instance->irq != SCSI_IRQ_NONE)
free_irq(instance->irq, NULL);
return 0; return 0;
} }
......
...@@ -326,6 +326,7 @@ int macscsi_release (struct Scsi_Host *shpnt) ...@@ -326,6 +326,7 @@ int macscsi_release (struct Scsi_Host *shpnt)
{ {
if (shpnt->irq != SCSI_IRQ_NONE) if (shpnt->irq != SCSI_IRQ_NONE)
free_irq (shpnt->irq, NCR5380_intr); free_irq (shpnt->irq, NCR5380_intr);
NCR5380_exit(shpnt);
return 0; return 0;
} }
......
...@@ -605,6 +605,7 @@ static int pas16_release(struct Scsi_Host *shost) ...@@ -605,6 +605,7 @@ static int pas16_release(struct Scsi_Host *shost)
{ {
if (shost->irq) if (shost->irq)
free_irq(shost->irq, NULL); free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->dma_channel != 0xff) if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel); free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port) if (shost->io_port && shost->n_io_port)
......
...@@ -284,6 +284,7 @@ static int t128_release(struct Scsi_Host *shost) ...@@ -284,6 +284,7 @@ static int t128_release(struct Scsi_Host *shost)
{ {
if (shost->irq) if (shost->irq)
free_irq(shost->irq, NULL); free_irq(shost->irq, NULL);
NCR5380_exit(shost);
if (shost->io_port && shost->n_io_port) if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port); release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost); scsi_unregister(shost);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment