Commit eda32612 authored by Christoph Hellwig's avatar Christoph Hellwig

[PATCH] give all LLDD driver a ->release method

This allows us to kill the horrible scsi_host_legacy_release hack.
Note that the new ->release methods still seem to be incorrect in
some case, but I really want to kill that hack in core code not
to make all drivers perfect.
parent b868f1d5
......@@ -590,6 +590,21 @@ static int __init NCR53c406a_detect(Scsi_Host_Template * tpnt)
return 0;
}
static int NCR53c406a_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
#ifdef USE_DMA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
#endif
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/* called from init/main.c */
static void __init NCR53c406a_setup(char *str, int *ints)
{
......@@ -1074,6 +1089,7 @@ static Scsi_Host_Template driver_template =
.proc_name = "NCR53c406a" /* proc_name */,
.name = "NCR53c406a" /* name */,
.detect = NCR53c406a_detect /* detect */,
.release = NCR53c406a_release,
.info = NCR53c406a_info /* info */,
.command = NCR53c406a_command /* command */,
.queuecommand = NCR53c406a_queue /* queuecommand */,
......
......@@ -1325,6 +1325,18 @@ static int __init aha1542_detect(Scsi_Host_Template * tpnt)
return count;
}
static int aha1542_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static int aha1542_restart(struct Scsi_Host *shost)
{
int i;
......@@ -1817,6 +1829,7 @@ static Scsi_Host_Template driver_template = {
.proc_name = "aha1542",
.name = "Adaptec 1542",
.detect = aha1542_detect,
.release = aha1542_release,
.command = aha1542_command,
.queuecommand = aha1542_queuecommand,
.eh_abort_handler = aha1542_abort,
......
......@@ -567,6 +567,16 @@ static int aha1740_detect(Scsi_Host_Template * tpnt)
return count;
}
static int aha1740_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static int aha1740_biosparam(struct scsi_device *sdev, struct block_device *dev,
sector_t capacity, int* ip)
{
......@@ -596,6 +606,7 @@ static Scsi_Host_Template driver_template = {
.proc_info = aha1740_proc_info,
.name = "Adaptec 174x (EISA)",
.detect = aha1740_detect,
.release = aha1740_release,
.command = aha1740_command,
.queuecommand = aha1740_queuecommand,
.bios_param = aha1740_biosparam,
......
......@@ -134,9 +134,22 @@ int __init amiga7xx_detect(Scsi_Host_Template *tpnt)
return num;
}
static int amiga7xx_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.name = "Amiga NCR53c710 SCSI",
.detect = amiga7xx_detect,
.release = amiga7xx_release,
.queuecommand = NCR53c7xx_queue_command,
.abort = NCR53c7xx_abort,
.reset = NCR53c7xx_reset,
......
......@@ -51,9 +51,22 @@ int bvme6000_scsi_detect(Scsi_Host_Template *tpnt)
return 1;
}
static int mvme6000_scsi_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.name = "BVME6000 NCR53c710 SCSI",
.detect = bvme6000_scsi_detect,
.release = bvme6000_scsi_release,
.queuecommand = NCR53c7xx_queue_command,
.abort = NCR53c7xx_abort,
.reset = NCR53c7xx_reset,
......
......@@ -109,11 +109,22 @@ static void scsi_dma_int(int, void *, struct pt_regs *);
int dec_esp_detect(Scsi_Host_Template * tpnt);
static int dec_esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.proc_name = "esp",
.proc_info = &esp_proc_info,
.name = "NCR53C94",
.detect = dec_esp_detect,
.release = dec_esp_release,
.info = esp_info,
.command = esp_command,
.queuecommand = esp_queue,
......
......@@ -447,9 +447,20 @@ MODULE_LICENSE("GPL");
#include "NCR5380.c"
static int dtc_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.name = "DTC 3180/3280 ",
.detect = dtc_detect,
.release = dtc_release,
.queuecommand = dtc_queue_command,
.eh_abort_handler = dtc_abort,
.eh_bus_reset_handler = dtc_bus_reset,
......
......@@ -1237,6 +1237,17 @@ static int esp_release(struct Scsi_Host *host)
return 0;
}
/* this is clearly wrong for esp.. */
static int esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/* The info function will return whatever useful
* information the developer sees fit. If not provided, then
* the name field will be used instead.
......@@ -4384,12 +4395,12 @@ static void esp_slave_destroy(Scsi_Device *SDptr)
SDptr->hostdata = NULL;
}
static Scsi_Host_Template driver_template = {
.proc_name = "esp",
.proc_info = esp_proc_info,
.name = "Sun ESP 100/100a/200",
.detect = esp_detect,
.release = esp_release,
.slave_alloc = esp_slave_alloc,
.slave_destroy = esp_slave_destroy,
.release = esp_release,
......
......@@ -34,11 +34,9 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/completion.h>
#include <linux/unistd.h>
#include <asm/dma.h>
#include "scsi.h"
#include "hosts.h"
......@@ -172,28 +170,6 @@ int scsi_tp_for_each_host(Scsi_Host_Template *shost_tp, int
return 0;
}
/**
* scsi_host_legacy_release - default release function for hosts
* @shost:
*
* Description:
* This is the default case for the release function. Its completely
* useless for anything but old ISA adapters
**/
static int scsi_host_legacy_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
#ifdef CONFIG_GENERIC_ISA_DMA
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
#endif
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
return 0;
}
/**
* scsi_remove_host - check a scsi host for release and release
* @shost: a pointer to a scsi host to release
......@@ -445,7 +421,9 @@ int scsi_register_host(Scsi_Host_Template *shost_tp)
printk(KERN_WARNING
"scsi HBA driver %s didn't set a release method, "
"please fix the template\n", shost_tp->name);
shost_tp->release = &scsi_host_legacy_release;
dump_stack();
return -EINVAL;
}
shost_tp->detect(shost_tp);
......
......@@ -139,6 +139,18 @@ int jazz_esp_detect(Scsi_Host_Template *tpnt)
return 0;
}
static int jazz_esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/************************************************************* DMA Functions */
static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
{
......@@ -278,6 +290,7 @@ static Scsi_Host_Template driver_template = {
.proc_info = &esp_proc_info,
.name = "ESP 100/100a/200",
.detect = jazz_esp_detect,
.release = jazz_esp_release,
.info = esp_info,
.command = esp_command,
.queuecommand = esp_queue,
......
......@@ -464,6 +464,16 @@ int mac_esp_detect(Scsi_Host_Template * tpnt)
return chipspresent;
}
static int mac_esp_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/*
* I've been wondering what this is supposed to do, for some time. Talking
* to Allen Briggs: These machines have an extra register someplace where the
......@@ -717,6 +727,7 @@ static Scsi_Host_Template driver_template = {
.proc_name = "esp",
.name = "Mac 53C9x SCSI",
.detect = mac_esp_detect,
.release = mac_esp_release,
.info = esp_info,
/* .command = esp_command, */
.queuecommand = esp_queue,
......
......@@ -53,9 +53,22 @@ int mvme16x_scsi_detect(Scsi_Host_Template *tpnt)
return 1;
}
static int mvme16x_scsi_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.name = "MVME16x NCR53c710 SCSI",
.detect = mvme16x_scsi_detect,
.release = mvme16x_scsi_release,
.queuecommand = NCR53c7xx_queue_command,
.abort = NCR53c7xx_abort,
.reset = NCR53c7xx_reset,
......
......@@ -600,9 +600,22 @@ static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src
#include "NCR5380.c"
static int pas16_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static Scsi_Host_Template driver_template = {
.name = "Pro Audio Spectrum-16 SCSI",
.detect = pas16_detect,
.release = pas16_release,
.queuecommand = pas16_queue_command,
.eh_abort_handler = pas16_abort,
.eh_bus_reset_handler = pas16_bus_reset,
......
......@@ -655,6 +655,17 @@ int Psi240i_Detect (Scsi_Host_Template *tpnt)
}
return count;
}
static int Psi240i_Release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/****************************************************************
* Name: Psi240i_Abort
*
......@@ -722,6 +733,7 @@ static Scsi_Host_Template driver_template = {
.proc_name = "psi240i",
.name = "PSI-240I EIDE Disk Controller",
.detect = Psi240i_Detect,
.release = Psi240i_Release,
.command = Psi240i_Command,
.queuecommand = Psi240i_QueueCommand,
.abort = Psi240i_Abort,
......
......@@ -739,6 +739,18 @@ int __devinit qlogicfas_detect(Scsi_Host_Template *sht)
return (__qlogicfas_detect(sht) != NULL);
}
static int qlogicfas_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/*
* Return bios parameters
*/
......@@ -826,6 +838,7 @@ Scsi_Host_Template qlogicfas_driver_template = {
.name = "qlogicfas",
.proc_name = "qlogicfas",
.detect = qlogicfas_detect,
.release = qlogicfas_release,
.info = qlogicfas_info,
.command = qlogicfas_command,
.queuecommand = qlogicfas_queuecommand,
......
......@@ -280,6 +280,16 @@ int __init t128_detect(Scsi_Host_Template * tpnt){
return count;
}
static int t128_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/*
* Function : int t128_biosparam(Disk * disk, struct block_device *dev, int *ip)
*
......@@ -403,6 +413,7 @@ MODULE_LICENSE("GPL");
static Scsi_Host_Template driver_template = {
.name = "Trantor T128/T128F/T228",
.detect = t128_detect,
.release = t128_release,
.queuecommand = t128_queue_command,
.eh_abort_handler = t128_abort,
.eh_bus_reset_handler = t128_bus_reset,
......
......@@ -643,6 +643,18 @@ static int ultrastor_detect(Scsi_Host_Template * tpnt)
return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
}
static int ultrastor_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->dma_channel != 0xff)
free_dma(shost->dma_channel);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
static const char *ultrastor_info(struct Scsi_Host * shpnt)
{
static char buf[64];
......@@ -1177,6 +1189,7 @@ MODULE_LICENSE("GPL");
static Scsi_Host_Template driver_template = {
.name = "UltraStor 14F/24F/34F",
.detect = ultrastor_detect,
.release = ultrastor_release,
.info = ultrastor_info,
.queuecommand = ultrastor_queuecommand,
.eh_abort_handler = ultrastor_abort,
......
......@@ -1616,6 +1616,15 @@ static int wd7000_detect(Scsi_Host_Template * tpnt)
return (present);
}
static int wd7000_release(struct Scsi_Host *shost)
{
if (shost->irq)
free_irq(shost->irq, NULL);
if (shost->io_port && shost->n_io_port)
release_region(shost->io_port, shost->n_io_port);
scsi_unregister(shost);
return 0;
}
/*
* I have absolutely NO idea how to do an abort with the WD7000...
......@@ -1722,6 +1731,7 @@ static Scsi_Host_Template driver_template = {
.proc_info = wd7000_proc_info,
.name = "Western Digital WD-7000",
.detect = wd7000_detect,
.release = wd7000_release,
.command = wd7000_command,
.queuecommand = wd7000_queuecommand,
.eh_bus_reset_handler = wd7000_bus_reset,
......
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