Commit 52839747 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by James Bottomley

[PATCH] scsi_add_host/scsi_Remove_host for aic7xxx/aic79xx

I remember having this submitted a while ago, but here's the code
again, this time with the untested aic79xx bits.
parent 44b2383d
......@@ -801,7 +801,6 @@ ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb,
/************************ Host template entry points *************************/
static int ahd_linux_detect(Scsi_Host_Template *);
static int ahd_linux_release(struct Scsi_Host *);
static const char *ahd_linux_info(struct Scsi_Host *);
static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
......@@ -811,6 +810,7 @@ static void ahd_linux_slave_destroy(Scsi_Device *);
static int ahd_linux_biosparam(struct scsi_device*,
struct block_device*, sector_t, int[]);
#else
static int ahd_linux_release(struct Scsi_Host *);
static void ahd_linux_select_queue_depth(struct Scsi_Host *host,
Scsi_Device *scsi_devs);
static int ahd_linux_biosparam(Disk *, kdev_t, int[]);
......@@ -874,7 +874,7 @@ ahd_linux_detect(Scsi_Host_Template *template)
ahd_list_lockinit();
#ifdef CONFIG_PCI
ahd_linux_pci_probe(template);
ahd_linux_pci_init();
#endif
/*
......@@ -894,6 +894,7 @@ ahd_linux_detect(Scsi_Host_Template *template)
return (found);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* Free the passed in Scsi_Host memory structures prior to unloading the
* module.
......@@ -925,6 +926,7 @@ ahd_linux_release(struct Scsi_Host * host)
ahd_list_unlock(&l);
return (0);
}
#endif
/*
* Return a string describing the driver.
......@@ -1664,9 +1666,9 @@ ahd_linux_bus_reset(Scsi_Cmnd *cmd)
}
Scsi_Host_Template aic79xx_driver_template = {
.module = THIS_MODULE,
.name = "aic79xx",
.proc_info = ahd_linux_proc_info,
.detect = ahd_linux_detect,
.release = ahd_linux_release,
.info = ahd_linux_info,
.queuecommand = ahd_linux_queue,
.eh_abort_handler = ahd_linux_abort,
......@@ -1698,18 +1700,17 @@ Scsi_Host_Template aic79xx_driver_template = {
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
.name = "aic79xx",
.slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure,
.slave_destroy = ahd_linux_slave_destroy,
#else
.detect = ahd_linux_detect,
.release = ahd_linux_release,
.select_queue_depths = ahd_linux_select_queue_depth,
.use_new_eh_code = 1,
#endif
};
#define driver_template aic79xx_driver_template
#include "scsi_module.c"
/**************************** Tasklet Handler *********************************/
static void
......@@ -2381,9 +2382,8 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
ahd_set_name(ahd, new_name);
}
host->unique_id = ahd->unit;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
scsi_set_device(host, &ahd->dev_softc->dev);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \
LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
scsi_set_pci_device(host, ahd->dev_softc);
#endif
ahd_linux_initialize_scsi_bus(ahd);
......@@ -2410,6 +2410,10 @@ ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template)
ahd_intr_enable(ahd, TRUE);
ahd_linux_start_dv(ahd);
ahd_unlock(ahd, &s);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
scsi_add_host(host, &ahd->dev_softc->dev);
#endif
return (0);
}
......@@ -2556,8 +2560,12 @@ ahd_platform_free(struct ahd_softc *ahd)
__WCLONE) == -ERESTARTSYS);
}
ahd_teardown_runq_tasklet(ahd);
if (ahd->platform_data->host != NULL)
if (ahd->platform_data->host != NULL) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
scsi_remove_host(ahd->platform_data->host);
#endif
scsi_unregister(ahd->platform_data->host);
}
/* destroy all of the device and target objects */
for (i = 0; i < AHD_NUM_TARGETS; i++) {
......@@ -2595,21 +2603,17 @@ ahd_platform_free(struct ahd_softc *ahd)
0x1000);
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
/* XXX Need an instance detach in the PCI code */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) && \
LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
/*
* In 2.4 we detach from the scsi midlayer before the PCI
* layer invokes our remove callback.
*/
if (ahd->dev_softc != NULL)
ahd->dev_softc->driver = NULL;
#endif
free(ahd->platform_data, M_DEVBUF);
}
if (TAILQ_EMPTY(&ahd_tailq)) {
unregister_reboot_notifier(&ahd_linux_notifier);
#ifdef CONFIG_PCI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
pci_unregister_driver(&aic79xx_pci_driver);
#endif
#endif
}
}
void
......@@ -5315,3 +5319,30 @@ ahd_platform_dump_card_state(struct ahd_softc *ahd)
}
}
}
static int __init ahd_linux_init(void)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
return (ahd_linux_detect(&aic79xx_driver_template) ? 0 : -ENODEV);
#else
scsi_register_module(MODULE_SCSI_HA, &aic79xx_driver_template);
if (!driver_template.present) {
scsi_unregister_module(MODULE_SCSI_HA,
&aic79xx_driver_template);
return (-ENODEV);
}
return (0);
#endif
}
static void __exit ahd_linux_exit(void)
{
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
scsi_unregister_module(MODULE_SCSI_HA, &aic79xx_driver_template);
#endif
ahd_linux_pci_exit();
}
module_init(ahd_linux_init);
module_exit(ahd_linux_exit);
......@@ -952,7 +952,8 @@ void ahd_power_state_change(struct ahd_softc *ahd,
#include <linux/bios32.h>
#endif
int ahd_linux_pci_probe(Scsi_Host_Template *);
int ahd_linux_pci_init(void);
void ahd_linux_pci_exit(void);
int ahd_pci_map_registers(struct ahd_softc *ahd);
int ahd_pci_map_int(struct ahd_softc *ahd);
......
......@@ -183,14 +183,21 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
pci_set_drvdata(pdev, ahd);
if (aic79xx_detect_complete)
if (aic79xx_detect_complete) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahd_linux_register_host(ahd, &aic79xx_driver_template);
#else
printf("aic79xx: ignoring PCI device found after "
"initialization\n");
return (-ENODEV);
#endif
}
#endif
return (0);
}
int
ahd_linux_pci_probe(Scsi_Host_Template *template)
ahd_linux_pci_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
return (pci_module_init(&aic79xx_pci_driver));
......@@ -219,6 +226,12 @@ ahd_linux_pci_probe(Scsi_Host_Template *template)
#endif
}
void
ahd_linux_pci_exit(void)
{
pci_unregister_driver(&aic79xx_pci_driver);
}
static int
ahd_linux_pci_reserve_io_regions(struct ahd_softc *ahd, u_long *base,
u_long *base2)
......
......@@ -875,7 +875,7 @@ ahc_linux_detect(Scsi_Host_Template *template)
ahc_list_lockinit();
#ifdef CONFIG_PCI
ahc_linux_pci_probe(template);
ahc_linux_pci_init();
#endif
if (aic7xxx_no_probe == 0)
......@@ -1266,9 +1266,9 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd)
}
Scsi_Host_Template aic7xxx_driver_template = {
.module = THIS_MODULE,
.name = "aic7xxx",
.proc_info = ahc_linux_proc_info,
.detect = ahc_linux_detect,
.release = ahc_linux_release,
.info = ahc_linux_info,
.queuecommand = ahc_linux_queue,
.eh_abort_handler = ahc_linux_abort,
......@@ -1300,19 +1300,17 @@ Scsi_Host_Template aic7xxx_driver_template = {
#endif
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
.name = "aic7xxx",
.slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure,
.slave_destroy = ahc_linux_slave_destroy,
#else
.detect = ahc_linux_detect,
.release = ahc_linux_release,
.select_queue_depths = ahc_linux_select_queue_depth,
.use_new_eh_code = 1,
#endif
};
#define driver_template aic7xxx_driver_template
#include "scsi_module.c"
/**************************** Tasklet Handler *********************************/
static void
......@@ -1861,9 +1859,8 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
ahc_set_name(ahc, new_name);
}
host->unique_id = ahc->unit;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
scsi_set_device(host, &ahc->dev_softc->dev);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) && \
LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
scsi_set_pci_device(host, ahc->dev_softc);
#endif
ahc_linux_initialize_scsi_bus(ahc);
......@@ -1897,6 +1894,10 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template)
ahc_intr_enable(ahc, TRUE);
ahc_linux_start_dv(ahc);
ahc_unlock(ahc, &s);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL));
#endif
return (0);
}
......@@ -2075,8 +2076,12 @@ ahc_platform_free(struct ahc_softc *ahc)
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
tasklet_kill(&ahc->platform_data->runq_tasklet);
#endif
if (ahc->platform_data->host != NULL)
if (ahc->platform_data->host != NULL) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
scsi_remove_host(ahc->platform_data->host);
#endif
scsi_unregister(ahc->platform_data->host);
}
/* destroy all of the device and target objects */
for (i = 0; i < AHC_NUM_TARGETS; i++) {
......@@ -2112,19 +2117,16 @@ ahc_platform_free(struct ahc_softc *ahc)
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
/* XXX Need an instance detach in the PCI code */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/*
* In 2.4 we detach from the scsi midlayer before the PCI
* layer invokes our remove callback.
*/
if (ahc->dev_softc != NULL)
ahc->dev_softc->driver = NULL;
#endif
free(ahc->platform_data, M_DEVBUF);
}
if (TAILQ_EMPTY(&ahc_tailq)) {
unregister_reboot_notifier(&ahc_linux_notifier);
#ifdef CONFIG_PCI
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
pci_unregister_driver(&aic7xxx_pci_driver);
#endif
#endif
free(ahc->platform_data, M_DEVBUF);
}
}
......@@ -5182,3 +5184,51 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc)
}
}
}
static int __init ahc_linux_init(void)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
return (ahc_linux_detect(&aic7xxx_driver_template) ? 0 : -ENODEV);
#else
scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
if (!driver_template.present) {
scsi_unregister_module(MODULE_SCSI_HA,
&aic7xxx_driver_template);
return (-ENODEV);
}
return (0);
#endif
}
static void __exit ahc_linux_exit(void)
{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
struct ahc_softc *ahc;
ahc_linux_pci_exit();
/*
* Get rid of the non-pci devices.
*
* XXX(hch): switch over eisa support to new LDM-based API
*/
TAILQ_FOREACH(ahc, &ahc_tailq, links)
ahc_linux_release(ahc->platform_data->host);
#else
scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template);
/*
* In 2.4 we have to unregister from the PCI core _after_
* unregistering from the scsi midlayer to avoid danling references.
*
* The 2.4 scsi midlayer is so f***ed..
*/
ahc_linux_pci_exit();
#endif
unregister_reboot_notifier(&ahc_linux_notifier);
}
module_init(ahc_linux_init);
module_exit(ahc_linux_exit);
......@@ -912,7 +912,8 @@ int aic7770_map_int(struct ahc_softc *ahc, u_int irq);
#include <linux/bios32.h>
#endif
int ahc_linux_pci_probe(Scsi_Host_Template *);
int ahc_linux_pci_init(void);
void ahc_linux_pci_exit(void);
int ahc_pci_map_registers(struct ahc_softc *ahc);
int ahc_pci_map_int(struct ahc_softc *ahc);
......
......@@ -179,14 +179,21 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
pci_set_drvdata(pdev, ahc);
if (aic7xxx_detect_complete)
if (aic7xxx_detect_complete) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
ahc_linux_register_host(ahc, &aic7xxx_driver_template);
#else
printf("aic7xxx: ignoring PCI device found after "
"initialization\n");
return (-ENODEV);
#endif
}
#endif
return (0);
}
int
ahc_linux_pci_probe(Scsi_Host_Template *template)
ahc_linux_pci_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
return (pci_module_init(&aic7xxx_pci_driver));
......@@ -215,6 +222,12 @@ ahc_linux_pci_probe(Scsi_Host_Template *template)
#endif
}
void
ahc_linux_pci_exit(void)
{
pci_unregister_driver(&aic7xxx_pci_driver);
}
static int
ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, u_long *base)
{
......
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