diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 10:00:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-11 10:00:50 -0700 |
commit | 0c4ea957c6ec953d84cc07346437abe0ae4bb57d (patch) | |
tree | aea0141a8afb37743604aa909c6ea7362367ae25 | |
parent | f2c60ed038dedcc43a0eb3ef4e0602741ba90384 (diff) | |
parent | df9f54084f1faf611cedd846d38b0631f9d4e9a5 (diff) | |
download | blackbird-op-linux-0c4ea957c6ec953d84cc07346437abe0ae4bb57d.tar.gz blackbird-op-linux-0c4ea957c6ec953d84cc07346437abe0ae4bb57d.zip |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22
* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22:
Convert SGI IP22 and specific drivers to platform_device.
-rw-r--r-- | arch/mips/sgi-ip22/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/sgi-ip22/ip22-platform.c | 177 | ||||
-rw-r--r-- | drivers/net/sgiseeq.c | 83 | ||||
-rw-r--r-- | drivers/scsi/sgiwd93.c | 264 | ||||
-rw-r--r-- | include/asm-mips/sgi/seeq.h | 21 | ||||
-rw-r--r-- | include/asm-mips/sgi/wd.h | 20 |
6 files changed, 376 insertions, 191 deletions
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index b6d649241dc1..1fb3e353e212 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile @@ -4,6 +4,6 @@ # obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ - ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o + ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o obj-$(CONFIG_EISA) += ip22-eisa.o diff --git a/arch/mips/sgi-ip22/ip22-platform.c b/arch/mips/sgi-ip22/ip22-platform.c new file mode 100644 index 000000000000..78b608d2d4e1 --- /dev/null +++ b/arch/mips/sgi-ip22/ip22-platform.c @@ -0,0 +1,177 @@ +#include <linux/init.h> +#include <linux/if_ether.h> +#include <linux/kernel.h> +#include <linux/platform_device.h> + +#include <asm/paccess.h> +#include <asm/sgi/ip22.h> +#include <asm/sgi/hpc3.h> +#include <asm/sgi/mc.h> +#include <asm/sgi/seeq.h> +#include <asm/sgi/wd.h> + +static struct resource sgiwd93_0_resources[] = { + { + .name = "eth0 irq", + .start = SGI_WD93_0_IRQ, + .end = SGI_WD93_0_IRQ, + .flags = IORESOURCE_IRQ + } +}; + +static struct sgiwd93_platform_data sgiwd93_0_pd = { + .unit = 0, + .irq = SGI_WD93_0_IRQ, +}; + +static struct platform_device sgiwd93_0_device = { + .name = "sgiwd93", + .id = 0, + .num_resources = ARRAY_SIZE(sgiwd93_0_resources), + .resource = sgiwd93_0_resources, + .dev = { + .platform_data = &sgiwd93_0_pd, + }, +}; + +static struct resource sgiwd93_1_resources[] = { + { + .name = "eth0 irq", + .start = SGI_WD93_1_IRQ, + .end = SGI_WD93_1_IRQ, + .flags = IORESOURCE_IRQ + } +}; + +static struct sgiwd93_platform_data sgiwd93_1_pd = { + .unit = 1, + .irq = SGI_WD93_1_IRQ, +}; + +static struct platform_device sgiwd93_1_device = { + .name = "sgiwd93", + .id = 1, + .num_resources = ARRAY_SIZE(sgiwd93_1_resources), + .resource = sgiwd93_1_resources, + .dev = { + .platform_data = &sgiwd93_1_pd, + }, +}; + +/* + * Create a platform device for the GPI port that receives the + * image data from the embedded camera. + */ +static int __init sgiwd93_devinit(void) +{ + int res; + + sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0; + sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext; + + res = platform_device_register(&sgiwd93_0_device); + if (res) + return res; + + if (!ip22_is_fullhouse()) + return 0; + + sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1; + sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext; + + return platform_device_register(&sgiwd93_1_device); +} + +device_initcall(sgiwd93_devinit); + +static struct resource sgiseeq_0_resources[] = { + { + .name = "eth0 irq", + .start = SGI_ENET_IRQ, + .end = SGI_ENET_IRQ, + .flags = IORESOURCE_IRQ + } +}; + +static struct sgiseeq_platform_data eth0_pd; + +static struct platform_device eth0_device = { + .name = "sgiseeq", + .id = 0, + .num_resources = ARRAY_SIZE(sgiseeq_0_resources), + .resource = sgiseeq_0_resources, + .dev = { + .platform_data = ð0_pd, + }, +}; + +static struct resource sgiseeq_1_resources[] = { + { + .name = "eth1 irq", + .start = SGI_GIO_0_IRQ, + .end = SGI_GIO_0_IRQ, + .flags = IORESOURCE_IRQ + } +}; + +static struct sgiseeq_platform_data eth1_pd; + +static struct platform_device eth1_device = { + .name = "sgiseeq", + .id = 1, + .num_resources = ARRAY_SIZE(sgiseeq_1_resources), + .resource = sgiseeq_1_resources, + .dev = { + .platform_data = ð1_pd, + }, +}; + +/* + * Create a platform device for the GPI port that receives the + * image data from the embedded camera. + */ +static int __init sgiseeq_devinit(void) +{ + unsigned int tmp; + int res, i; + + eth0_pd.hpc = hpc3c0; + eth0_pd.irq = SGI_ENET_IRQ; +#define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { + unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i); + + eth0_pd.mac[2 * i] = tmp >> 8; + eth0_pd.mac[2 * i + 1] = tmp & 0xff; + } + + res = platform_device_register(ð0_device); + if (res) + return res; + + /* Second HPC is missing? */ + if (ip22_is_fullhouse() || + !get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1])) + return 0; + + sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 | + SGIMC_GIOPAR_HPC264; + hpc3c1->pbus_piocfg[0][0] = 0x3ffff; + /* interrupt/config register on Challenge S Mezz board */ + hpc3c1->pbus_extregs[0][0] = 0x30; + + eth1_pd.hpc = hpc3c1; + eth1_pd.irq = SGI_GIO_0_IRQ; +#define EADDR_NVOFS 250 + for (i = 0; i < 3; i++) { + unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom, + EADDR_NVOFS / 2 + i); + + eth1_pd.mac[2 * i] = tmp >> 8; + eth1_pd.mac[2 * i + 1] = tmp & 0xff; + } + + return platform_device_register(ð1_device); +} + +device_initcall(sgiseeq_devinit); diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 1fc77300b055..2106becf6990 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -16,11 +16,13 @@ #include <linux/string.h> #include <linux/delay.h> #include <linux/netdevice.h> +#include <linux/platform_device.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <asm/sgi/hpc3.h> #include <asm/sgi/ip22.h> +#include <asm/sgi/seeq.h> #include "sgiseeq.h" @@ -92,13 +94,9 @@ struct sgiseeq_private { struct net_device_stats stats; - struct net_device *next_module; spinlock_t tx_lock; }; -/* A list of all installed seeq devices, for removing the driver module. */ -static struct net_device *root_sgiseeq_dev; - static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) { hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; @@ -624,9 +622,12 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) -static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) +static int __init sgiseeq_probe(struct platform_device *pdev) { + struct sgiseeq_platform_data *pd = pdev->dev.platform_data; + struct hpc3_regs *hpcregs = pd->hpc; struct sgiseeq_init_block *sr; + unsigned int irq = pd->irq; struct sgiseeq_private *sp; struct net_device *dev; int err, i; @@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) err = -ENOMEM; goto err_out; } + + platform_set_drvdata(pdev, dev); sp = netdev_priv(dev); /* Make private data page aligned */ @@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) } sp->srings = sr; -#define EADDR_NVOFS 250 - for (i = 0; i < 3; i++) { - unsigned short tmp = has_eeprom ? - ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) : - ip22_nvram_read(EADDR_NVOFS / 2+i); - - dev->dev_addr[2 * i] = tmp >> 8; - dev->dev_addr[2 * i + 1] = tmp & 0xff; - } + memcpy(dev->dev_addr, pd->mac, ETH_ALEN); #ifdef DEBUG gpriv = sp; @@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); - sp->next_module = root_sgiseeq_dev; - root_sgiseeq_dev = dev; - return 0; err_out_free_page: @@ -734,43 +726,42 @@ err_out: return err; } -static int __init sgiseeq_probe(void) +static void __exit sgiseeq_remove(struct platform_device *pdev) { - unsigned int tmp, ret1, ret2 = 0; - - /* On board adapter on 1st HPC is always present */ - ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0); - /* Let's see if second HPC is there */ - if (!(ip22_is_fullhouse()) && - get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) { - sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | - SGIMC_GIOPAR_EXP164 | - SGIMC_GIOPAR_HPC264; - hpc3c1->pbus_piocfg[0][0] = 0x3ffff; - /* interrupt/config register on Challenge S Mezz board */ - hpc3c1->pbus_extregs[0][0] = 0x30; - ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1); - } + struct net_device *dev = platform_get_drvdata(pdev); + struct sgiseeq_private *sp = netdev_priv(dev); - return (ret1 & ret2) ? ret1 : 0; + unregister_netdev(dev); + free_page((unsigned long) sp->srings); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); } -static void __exit sgiseeq_exit(void) -{ - struct net_device *next, *dev; - struct sgiseeq_private *sp; +static struct platform_driver sgiseeq_driver = { + .probe = sgiseeq_probe, + .remove = __devexit_p(sgiseeq_remove), + .driver = { + .name = "sgiseeq" + } +}; - for (dev = root_sgiseeq_dev; dev; dev = next) { - sp = (struct sgiseeq_private *) netdev_priv(dev); - next = sp->next_module; - unregister_netdev(dev); - free_page((unsigned long) sp->srings); - free_netdev(dev); +static int __init sgiseeq_module_init(void) +{ + if (platform_driver_register(&sgiseeq_driver)) { + printk(KERN_ERR "Driver registration failed\n"); + return -ENODEV; } + + return 0; +} + +static void __exit sgiseeq_module_exit(void) +{ + platform_driver_unregister(&sgiseeq_driver); } -module_init(sgiseeq_probe); -module_exit(sgiseeq_exit); +module_init(sgiseeq_module_init); +module_exit(sgiseeq_module_exit); MODULE_DESCRIPTION("SGI Seeq 8003 driver"); MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>"); diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index a15752b37990..eef82758d047 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -6,87 +6,49 @@ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org) - * Copyright (C) 2003 Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) * * (In all truth, Jed Schimmel wrote all this code.) */ -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/types.h> -#include <linux/mm.h> -#include <linux/blkdev.h> + +#undef DEBUG + #include <linux/delay.h> #include <linux/dma-mapping.h> +#include <linux/gfp.h> +#include <linux/interrupt.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/module.h> +#include <linux/platform_device.h> #include <linux/spinlock.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/sgialib.h> -#include <asm/sgi/sgi.h> -#include <asm/sgi/mc.h> #include <asm/sgi/hpc3.h> #include <asm/sgi/ip22.h> -#include <asm/irq.h> -#include <asm/io.h> +#include <asm/sgi/wd.h> #include "scsi.h" -#include <scsi/scsi_host.h> #include "wd33c93.h" -#include <linux/stat.h> - -#if 0 -#define DPRINTK(args...) printk(args) -#else -#define DPRINTK(args...) -#endif - -#define HDATA(ptr) ((struct ip22_hostdata *)((ptr)->hostdata)) - struct ip22_hostdata { struct WD33C93_hostdata wh; struct hpc_data { dma_addr_t dma; - void * cpu; + void *cpu; } hd; }; +#define host_to_hostdata(host) ((struct ip22_hostdata *)((host)->hostdata)) + struct hpc_chunk { struct hpc_dma_desc desc; u32 _padding; /* align to quadword boundary */ }; -struct Scsi_Host *sgiwd93_host; -struct Scsi_Host *sgiwd93_host1; - -/* Wuff wuff, wuff, wd33c93.c, wuff wuff, object oriented, bow wow. */ -static inline void write_wd33c93_count(const wd33c93_regs regs, - unsigned long value) -{ - *regs.SASR = WD_TRANSFER_COUNT_MSB; - mb(); - *regs.SCMD = ((value >> 16) & 0xff); - *regs.SCMD = ((value >> 8) & 0xff); - *regs.SCMD = ((value >> 0) & 0xff); - mb(); -} - -static inline unsigned long read_wd33c93_count(const wd33c93_regs regs) -{ - unsigned long value; - - *regs.SASR = WD_TRANSFER_COUNT_MSB; - mb(); - value = ((*regs.SCMD & 0xff) << 16); - value |= ((*regs.SCMD & 0xff) << 8); - value |= ((*regs.SCMD & 0xff) << 0); - mb(); - return value; -} - static irqreturn_t sgiwd93_intr(int irq, void *dev_id) { - struct Scsi_Host * host = (struct Scsi_Host *) dev_id; + struct Scsi_Host * host = dev_id; unsigned long flags; spin_lock_irqsave(host->host_lock, flags); @@ -131,12 +93,12 @@ void fill_hpc_entries(struct hpc_chunk *hcp, struct scsi_cmnd *cmd, int datainp) static int dma_setup(struct scsi_cmnd *cmd, int datainp) { - struct ip22_hostdata *hdata = HDATA(cmd->device->host); + struct ip22_hostdata *hdata = host_to_hostdata(cmd->device->host); struct hpc3_scsiregs *hregs = (struct hpc3_scsiregs *) cmd->device->host->base; struct hpc_chunk *hcp = (struct hpc_chunk *) hdata->hd.cpu; - DPRINTK("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); + pr_debug("dma_setup: datainp<%d> hcp<%p> ", datainp, hcp); hdata->wh.dma_dir = datainp; @@ -151,7 +113,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) fill_hpc_entries(hcp, cmd, datainp); - DPRINTK(" HPCGO\n"); + pr_debug(" HPCGO\n"); /* Start up the HPC. */ hregs->ndptr = hdata->hd.dma; @@ -166,7 +128,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int datainp) static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, int status) { - struct ip22_hostdata *hdata = HDATA(instance); + struct ip22_hostdata *hdata = host_to_hostdata(instance); struct hpc3_scsiregs *hregs; if (!SCpnt) @@ -174,7 +136,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, hregs = (struct hpc3_scsiregs *) SCpnt->device->host->base; - DPRINTK("dma_stop: status<%d> ", status); + pr_debug("dma_stop: status<%d> ", status); /* First stop the HPC and flush it's FIFO. */ if (hdata->wh.dma_dir) { @@ -186,7 +148,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, dma_unmap_single(NULL, SCpnt->SCp.dma_handle, SCpnt->SCp.this_residual, SCpnt->sc_data_direction); - DPRINTK("\n"); + pr_debug("\n"); } void sgiwd93_reset(unsigned long base) @@ -216,29 +178,71 @@ static inline void init_hpc_chain(struct hpc_data *hd) hcp->desc.pnext = hd->dma; } -static struct Scsi_Host * __init sgiwd93_setup_scsi( - struct scsi_host_template *SGIblows, int unit, int irq, - struct hpc3_scsiregs *hregs, unsigned char *wdregs) +static int sgiwd93_bus_reset(struct scsi_cmnd *cmd) +{ + /* FIXME perform bus-specific reset */ + + /* FIXME 2: kill this function, and let midlayer fallback + to the same result, calling wd33c93_host_reset() */ + + spin_lock_irq(cmd->device->host->host_lock); + wd33c93_host_reset(cmd); + spin_unlock_irq(cmd->device->host->host_lock); + + return SUCCESS; +} + +/* + * Kludge alert - the SCSI code calls the abort and reset method with int + * arguments not with pointers. So this is going to blow up beautyfully + * on 64-bit systems with memory outside the compat address spaces. + */ +static struct scsi_host_template sgiwd93_template = { + .module = THIS_MODULE, + .proc_name = "SGIWD93", + .name = "SGI WD93", + .queuecommand = wd33c93_queuecommand, + .eh_abort_handler = wd33c93_abort, + .eh_bus_reset_handler = sgiwd93_bus_reset, + .eh_host_reset_handler = wd33c93_host_reset, + .can_queue = 16, + .this_id = 7, + .sg_tablesize = SG_ALL, + .cmd_per_lun = 8, + .use_clustering = DISABLE_CLUSTERING, +}; + +static int __init sgiwd93_probe(struct platform_device *pdev) { + struct sgiwd93_platform_data *pd = pdev->dev.platform_data; + unsigned char *wdregs = pd->wdregs; + struct hpc3_scsiregs *hregs = pd->hregs; struct ip22_hostdata *hdata; struct Scsi_Host *host; wd33c93_regs regs; - - host = scsi_register(SGIblows, sizeof(struct ip22_hostdata)); - if (!host) - return NULL; + unsigned int unit = pd->unit; + unsigned int irq = pd->irq; + int err; + + host = scsi_host_alloc(&sgiwd93_template, sizeof(struct ip22_hostdata)); + if (!host) { + err = -ENOMEM; + goto out; + } host->base = (unsigned long) hregs; host->irq = irq; - hdata = HDATA(host); - hdata->hd.cpu = dma_alloc_coherent(NULL, PAGE_SIZE, &hdata->hd.dma, - GFP_KERNEL); + hdata = host_to_hostdata(host); + hdata->hd.cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, + &hdata->hd.dma, GFP_KERNEL); if (!hdata->hd.cpu) { printk(KERN_WARNING "sgiwd93: Could not allocate memory for " "host %d buffer.\n", unit); - goto out_unregister; + err = -ENOMEM; + goto out_put; } + init_hpc_chain(&hdata->hd); regs.SASR = wdregs + 3; @@ -249,95 +253,67 @@ static struct Scsi_Host * __init sgiwd93_setup_scsi( if (hdata->wh.no_sync == 0xff) hdata->wh.no_sync = 0; - if (request_irq(irq, sgiwd93_intr, 0, "SGI WD93", (void *) host)) { + err = request_irq(irq, sgiwd93_intr, 0, "SGI WD93", host); + if (err) { printk(KERN_WARNING "sgiwd93: Could not register irq %d " "for host %d.\n", irq, unit); goto out_free; } - return host; -out_free: - dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); - wd33c93_release(); + platform_set_drvdata(pdev, host); -out_unregister: - scsi_unregister(host); + err = scsi_add_host(host, NULL); + if (err) + goto out_irq; - return NULL; -} - -static int __init sgiwd93_detect(struct scsi_host_template *SGIblows) -{ - int found = 0; - - SGIblows->proc_name = "SGIWD93"; - sgiwd93_host = sgiwd93_setup_scsi(SGIblows, 0, SGI_WD93_0_IRQ, - &hpc3c0->scsi_chan0, - (unsigned char *)hpc3c0->scsi0_ext); - if (sgiwd93_host) - found++; - - /* Set up second controller on the Indigo2 */ - if (ip22_is_fullhouse()) { - sgiwd93_host1 = sgiwd93_setup_scsi(SGIblows, 1, SGI_WD93_1_IRQ, - &hpc3c0->scsi_chan1, - (unsigned char *)hpc3c0->scsi1_ext); - if (sgiwd93_host1) - found++; - } - - return found; -} + scsi_scan_host(host); -static int sgiwd93_release(struct Scsi_Host *instance) -{ - struct ip22_hostdata *hdata = HDATA(instance); - int irq = 0; - - if (sgiwd93_host && sgiwd93_host == instance) - irq = SGI_WD93_0_IRQ; - else if (sgiwd93_host1 && sgiwd93_host1 == instance) - irq = SGI_WD93_1_IRQ; + return 0; - free_irq(irq, sgiwd93_intr); +out_irq: + free_irq(irq, host); +out_free: dma_free_coherent(NULL, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); - wd33c93_release(); +out_put: + scsi_host_put(host); +out: - return 1; + return err; } -static int sgiwd93_bus_reset(struct scsi_cmnd *cmd) +static void __exit sgiwd93_remove(struct platform_device *pdev) { - /* FIXME perform bus-specific reset */ + struct Scsi_Host *host = platform_get_drvdata(pdev); + struct ip22_hostdata *hdata = (struct ip22_hostdata *) host->hostdata; + struct sgiwd93_platform_data *pd = pdev->dev.platform_data; + + scsi_remove_host(host); + free_irq(pd->irq, host); + dma_free_coherent(&pdev->dev, PAGE_SIZE, hdata->hd.cpu, hdata->hd.dma); + scsi_host_put(host); +} - /* FIXME 2: kill this function, and let midlayer fallback - to the same result, calling wd33c93_host_reset() */ +static struct platform_driver sgiwd93_driver = { + .probe = sgiwd93_probe, + .remove = __devexit_p(sgiwd93_remove), + .driver = { + .name = "sgiwd93" + } +}; - spin_lock_irq(cmd->device->host->host_lock); - wd33c93_host_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); +static int __init sgiwd93_module_init(void) +{ + return platform_driver_register(&sgiwd93_driver); +} - return SUCCESS; +static void __exit sgiwd93_module_exit(void) +{ + return platform_driver_unregister(&sgiwd93_driver); } -/* - * Kludge alert - the SCSI code calls the abort and reset method with int - * arguments not with pointers. So this is going to blow up beautyfully - * on 64-bit systems with memory outside the compat address spaces. - */ -static struct scsi_host_template driver_template = { - .proc_name = "SGIWD93", - .name = "SGI WD93", - .detect = sgiwd93_detect, - .release = sgiwd93_release, - .queuecommand = wd33c93_queuecommand, - .eh_abort_handler = wd33c93_abort, - .eh_bus_reset_handler = sgiwd93_bus_reset, - .eh_host_reset_handler = wd33c93_host_reset, - .can_queue = 16, - .this_id = 7, - .sg_tablesize = SG_ALL, - .cmd_per_lun = 8, - .use_clustering = DISABLE_CLUSTERING, -}; -#include "scsi_module.c" +module_init(sgiwd93_module_init); +module_exit(sgiwd93_module_exit); + +MODULE_DESCRIPTION("SGI WD33C93 driver"); +MODULE_AUTHOR("Ralf Baechle <ralf@linux-mips.org>"); +MODULE_LICENSE("GPL"); diff --git a/include/asm-mips/sgi/seeq.h b/include/asm-mips/sgi/seeq.h new file mode 100644 index 000000000000..af0ffd76899d --- /dev/null +++ b/include/asm-mips/sgi/seeq.h @@ -0,0 +1,21 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 by Ralf Baechle + */ +#ifndef __ASM_SGI_SEEQ_H +#define __ASM_SGI_SEEQ_H + +#include <linux/if_ether.h> + +#include <asm/sgi/hpc3.h> + +struct sgiseeq_platform_data { + struct hpc3_regs *hpc; + unsigned int irq; + unsigned char mac[ETH_ALEN]; +}; + +#endif /* __ASM_SGI_SEEQ_H */ diff --git a/include/asm-mips/sgi/wd.h b/include/asm-mips/sgi/wd.h new file mode 100644 index 000000000000..0d6c3a4da891 --- /dev/null +++ b/include/asm-mips/sgi/wd.h @@ -0,0 +1,20 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2007 by Ralf Baechle + */ +#ifndef __ASM_SGI_WD_H +#define __ASM_SGI_WD_H + +#include <asm/sgi/hpc3.h> + +struct sgiwd93_platform_data { + unsigned int unit; + unsigned int irq; + struct hpc3_scsiregs *hregs; + unsigned char *wdregs; +}; + +#endif /* __ASM_SGI_WD_H */ |