From 87494404110f004ff8af3976333879460967c403 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 6 Feb 2004 14:44:47 +1100 Subject: [PATCH] ppc32: Update the PowerMac 53c94 SCSI driver Adapt to the "macio" driver infrastructure, cleanup IO accessors, remove local list of command/directions, uses infos provided by the SCSI layer. This driver certainly could use some more work. --- drivers/scsi/mac53c94.c | 503 ++++++++++++++++++---------------------- 1 file changed, 226 insertions(+), 277 deletions(-) diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 62a146b53b2d4..9415c2bbb2e0e 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -37,13 +38,12 @@ enum fsc_phase { }; struct fsc_state { - volatile struct mac53c94_regs *regs; + struct mac53c94_regs *regs; int intr; - volatile struct dbdma_regs *dma; + struct dbdma_regs *dma; int dmaintr; int clk_freq; struct Scsi_Host *host; - struct fsc_state *next; Scsi_Cmnd *request_q; Scsi_Cmnd *request_qtail; Scsi_Cmnd *current_req; /* req we're currently working on */ @@ -52,151 +52,23 @@ struct fsc_state { void *dma_cmd_space; struct pci_dev *pdev; dma_addr_t dma_addr; + struct macio_dev *mdev; }; -static struct fsc_state *all_53c94s; - static void mac53c94_init(struct fsc_state *); static void mac53c94_start(struct fsc_state *); static void mac53c94_interrupt(int, void *, struct pt_regs *); static irqreturn_t do_mac53c94_interrupt(int, void *, struct pt_regs *); static void cmd_done(struct fsc_state *, int result); static void set_dma_cmds(struct fsc_state *, Scsi_Cmnd *); -static int data_goes_out(Scsi_Cmnd *); - -int -mac53c94_detect(Scsi_Host_Template *tp) -{ - struct device_node *node; - int nfscs; - struct fsc_state *state, **prev_statep; - struct Scsi_Host *host; - void *dma_cmd_space; - unsigned char *clkprop; - int proplen; - struct pci_dev *pdev; - u8 pbus, devfn; - - nfscs = 0; - prev_statep = &all_53c94s; - for (node = find_devices("53c94"); node != 0; node = node->next) { - if (node->n_addrs != 2 || node->n_intrs != 2) { - printk(KERN_ERR "mac53c94: expected 2 addrs and intrs" - " (got %d/%d) for node %s\n", - node->n_addrs, node->n_intrs, node->full_name); - continue; - } - - pdev = NULL; - if (node->parent != NULL - && !pci_device_from_OF_node(node->parent, &pbus, &devfn)) - pdev = pci_find_slot(pbus, devfn); - if (pdev == NULL) { - printk(KERN_ERR "mac53c94: can't find PCI device " - "for %s\n", node->full_name); - continue; - } - - host = scsi_register(tp, sizeof(struct fsc_state)); - if (host == NULL) - break; - host->unique_id = nfscs; - - state = (struct fsc_state *) host->hostdata; - if (state == 0) { - /* "can't happen" */ - printk(KERN_ERR "mac53c94: no state for %s?!\n", - node->full_name); - scsi_unregister(host); - break; - } - state->host = host; - state->pdev = pdev; - - state->regs = (volatile struct mac53c94_regs *) - ioremap(node->addrs[0].address, 0x1000); - state->intr = node->intrs[0].line; - state->dma = (volatile struct dbdma_regs *) - ioremap(node->addrs[1].address, 0x1000); - state->dmaintr = node->intrs[1].line; - if (state->regs == NULL || state->dma == NULL) { - printk(KERN_ERR "mac53c94: ioremap failed for %s\n", - node->full_name); - if (state->dma != NULL) - iounmap(state->dma); - if (state->regs != NULL) - iounmap(state->regs); - scsi_unregister(host); - break; - } - - clkprop = get_property(node, "clock-frequency", &proplen); - if (clkprop == NULL || proplen != sizeof(int)) { - printk(KERN_ERR "%s: can't get clock frequency, " - "assuming 25MHz\n", node->full_name); - state->clk_freq = 25000000; - } else - state->clk_freq = *(int *)clkprop; - - /* Space for dma command list: +1 for stop command, - +1 to allow for aligning. */ - dma_cmd_space = kmalloc((host->sg_tablesize + 2) * - sizeof(struct dbdma_cmd), GFP_KERNEL); - if (dma_cmd_space == 0) { - printk(KERN_ERR "mac53c94: couldn't allocate dma " - "command space for %s\n", node->full_name); - goto err_cleanup; - } - state->dma_cmds = (struct dbdma_cmd *) - DBDMA_ALIGN(dma_cmd_space); - memset(state->dma_cmds, 0, (host->sg_tablesize + 1) - * sizeof(struct dbdma_cmd)); - state->dma_cmd_space = dma_cmd_space; - - *prev_statep = state; - prev_statep = &state->next; - - if (request_irq(state->intr, do_mac53c94_interrupt, 0, - "53C94", state)) { - printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", - state->intr, node->full_name); - err_cleanup: - iounmap(state->dma); - iounmap(state->regs); - scsi_unregister(host); - break; - } - mac53c94_init(state); - ++nfscs; - } - return nfscs; -} - -int -mac53c94_release(struct Scsi_Host *host) -{ - struct fsc_state *fp = (struct fsc_state *) host->hostdata; - - if (fp == 0) - return 0; - if (fp->regs) - iounmap((void *) fp->regs); - if (fp->dma) - iounmap((void *) fp->dma); - kfree(fp->dma_cmd_space); - free_irq(fp->intr, fp); - return 0; -} - -int -mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) +static int mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) { struct fsc_state *state; #if 0 - if (data_goes_out(cmd)) { + if (cmd->sc_data_direction == SCSI_DATA_WRITE) { int i; printk(KERN_DEBUG "mac53c94_queue %p: command is", cmd); for (i = 0; i < cmd->cmd_len; ++i) @@ -223,60 +95,52 @@ mac53c94_queue(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) return 0; } -int -mac53c94_abort(Scsi_Cmnd *cmd) +static int mac53c94_abort(Scsi_Cmnd *cmd) { return SCSI_ABORT_SNOOZE; } -int -mac53c94_host_reset(Scsi_Cmnd *cmd) +static int mac53c94_host_reset(Scsi_Cmnd *cmd) { struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata; - volatile struct mac53c94_regs *regs = state->regs; - volatile struct dbdma_regs *dma = state->dma; + struct mac53c94_regs *regs = state->regs; + struct dbdma_regs *dma = state->dma; st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); - regs->command = CMD_SCSI_RESET; /* assert RST */ - eieio(); + writeb(CMD_SCSI_RESET, ®s->command); /* assert RST */ udelay(100); /* leave it on for a while (>= 25us) */ - regs->command = CMD_RESET; - eieio(); + writeb(CMD_RESET, ®s->command); udelay(20); mac53c94_init(state); - regs->command = CMD_NOP; - eieio(); + writeb(CMD_NOP, ®s->command); return SUCCESS; } -static void -mac53c94_init(struct fsc_state *state) +static void mac53c94_init(struct fsc_state *state) { - volatile struct mac53c94_regs *regs = state->regs; - volatile struct dbdma_regs *dma = state->dma; + struct mac53c94_regs *regs = state->regs; + struct dbdma_regs *dma = state->dma; int x; - regs->config1 = state->host->this_id | CF1_PAR_ENABLE; - regs->sel_timeout = TIMO_VAL(250); /* 250ms */ - regs->clk_factor = CLKF_VAL(state->clk_freq); - regs->config2 = CF2_FEATURE_EN; - regs->config3 = 0; - regs->sync_period = 0; - regs->sync_offset = 0; - eieio(); - x = regs->interrupt; - st_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + writeb(state->host->this_id | CF1_PAR_ENABLE, ®s->config1); + writeb(TIMO_VAL(250), ®s->sel_timeout); /* 250ms */ + writeb(CLKF_VAL(state->clk_freq), ®s->clk_factor); + writeb(CF2_FEATURE_EN, ®s->config2); + writeb(0, ®s->config3); + writeb(0, ®s->sync_period); + writeb(0, ®s->sync_offset); + x = readb(®s->interrupt); + writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); } /* * Start the next command for a 53C94. * Should be called with interrupts disabled. */ -static void -mac53c94_start(struct fsc_state *state) +static void mac53c94_start(struct fsc_state *state) { Scsi_Cmnd *cmd; - volatile struct mac53c94_regs *regs = state->regs; + struct mac53c94_regs *regs = state->regs; int i; if (state->phase != idle || state->current_req != NULL) @@ -287,37 +151,30 @@ mac53c94_start(struct fsc_state *state) state->request_q = (Scsi_Cmnd *) cmd->host_scribble; /* Off we go */ - regs->count_lo = 0; - regs->count_mid = 0; - regs->count_hi = 0; - eieio(); - regs->command = CMD_NOP + CMD_DMA_MODE; + writeb(0, ®s->count_lo); + writeb(0, ®s->count_mid); + writeb(0, ®s->count_hi); + writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); udelay(1); - eieio(); - regs->command = CMD_FLUSH; + writeb(CMD_FLUSH, ®s->command); udelay(1); - eieio(); - regs->dest_id = cmd->device->id; - regs->sync_period = 0; - regs->sync_offset = 0; - eieio(); + writeb(cmd->device->id, ®s->dest_id); + writeb(0, ®s->sync_period); + writeb(0, ®s->sync_offset); /* load the command into the FIFO */ - for (i = 0; i < cmd->cmd_len; ++i) { - regs->fifo = cmd->cmnd[i]; - eieio(); - } + for (i = 0; i < cmd->cmd_len; ++i) + writeb(cmd->cmnd[i], ®s->fifo); /* do select without ATN XXX */ - regs->command = CMD_SELECT; + writeb(CMD_SELECT, ®s->command); state->phase = selecting; if (cmd->use_sg > 0 || cmd->request_bufflen != 0) set_dma_cmds(state, cmd); } -static irqreturn_t -do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) +static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { unsigned long flags; struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host; @@ -328,12 +185,11 @@ do_mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) return IRQ_HANDLED; } -static void -mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) +static void mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) { struct fsc_state *state = (struct fsc_state *) dev_id; - volatile struct mac53c94_regs *regs = state->regs; - volatile struct dbdma_regs *dma = state->dma; + struct mac53c94_regs *regs = state->regs; + struct dbdma_regs *dma = state->dma; Scsi_Cmnd *cmd = state->current_req; int nb, stat, seq, intr; static int mac53c94_errors; @@ -343,9 +199,9 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) * Apparently, reading the interrupt register unlatches * the status and sequence step registers. */ - seq = regs->seqstep; - stat = regs->status; - intr = regs->interrupt; + seq = readb(®s->seqstep); + stat = readb(®s->status); + intr = readb(®s->interrupt); #if 0 printk(KERN_DEBUG "mac53c94_intr, intr=%x stat=%x seq=%x phase=%d\n", @@ -355,8 +211,8 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) if (intr & INTR_RESET) { /* SCSI bus was reset */ printk(KERN_INFO "external SCSI bus reset detected\n"); - regs->command = CMD_NOP; - st_le32(&dma->control, RUN << 16); /* stop dma */ + writeb(CMD_NOP, ®s->command); + writel(RUN << 16, &dma->control); /* stop dma */ cmd_done(state, DID_RESET << 16); return; } @@ -373,8 +229,7 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) intr, stat, seq, state->phase); #endif ++mac53c94_errors; - regs->command = CMD_NOP + CMD_DMA_MODE; - eieio(); + writeb(CMD_NOP + CMD_DMA_MODE, ®s->command); } if (cmd == 0) { printk(KERN_DEBUG "53c94: interrupt with no command active?\n"); @@ -402,7 +257,7 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) cmd_done(state, DID_ERROR << 16); return; } - regs->command = CMD_NOP; + writeb(CMD_NOP, ®s->command); /* set DMA controller going if any data to transfer */ if ((stat & (STAT_MSG|STAT_CD)) == 0 && (cmd->use_sg > 0 || cmd->request_bufflen != 0)) { @@ -410,20 +265,17 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) if (nb > 0xfff0) nb = 0xfff0; cmd->SCp.this_residual -= nb; - regs->count_lo = nb; - regs->count_mid = nb >> 8; - eieio(); - regs->command = CMD_DMA_MODE + CMD_NOP; - eieio(); - st_le32(&dma->cmdptr, virt_to_phys(state->dma_cmds)); - st_le32(&dma->control, (RUN << 16) | RUN); - eieio(); - regs->command = CMD_DMA_MODE + CMD_XFER_DATA; + writeb(nb, ®s->count_lo); + writeb(nb >> 8, ®s->count_mid); + writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); + writel(virt_to_phys(state->dma_cmds), &dma->cmdptr); + writel((RUN << 16) | RUN, &dma->control); + writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); state->phase = dataing; break; } else if ((stat & STAT_PHASE) == STAT_CD + STAT_IO) { /* up to status phase already */ - regs->command = CMD_I_COMPLETE; + writeb(CMD_I_COMPLETE, ®s->command); state->phase = completing; } else { printk(KERN_DEBUG "in unexpected phase %x after cmd\n", @@ -446,18 +298,16 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) if (nb > 0xfff0) nb = 0xfff0; cmd->SCp.this_residual -= nb; - regs->count_lo = nb; - regs->count_mid = nb >> 8; - eieio(); - regs->command = CMD_DMA_MODE + CMD_NOP; - eieio(); - regs->command = CMD_DMA_MODE + CMD_XFER_DATA; + writeb(nb, ®s->count_lo); + writeb(nb >> 8, ®s->count_mid); + writeb(CMD_DMA_MODE + CMD_NOP, ®s->command); + writeb(CMD_DMA_MODE + CMD_XFER_DATA, ®s->command); break; } if ((stat & STAT_PHASE) != STAT_CD + STAT_IO) { printk(KERN_DEBUG "intr %x before data xfer complete\n", intr); } - out_le32(&dma->control, RUN << 16); /* stop dma */ + writel(RUN << 16, &dma->control); /* stop dma */ dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); if (cmd->use_sg != 0) { pci_unmap_sg(state->pdev, @@ -468,7 +318,7 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) cmd->request_bufflen, dma_dir); } /* should check dma status */ - regs->command = CMD_I_COMPLETE; + writeb(CMD_I_COMPLETE, ®s->command); state->phase = completing; break; case completing: @@ -477,10 +327,10 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) cmd_done(state, DID_ERROR << 16); return; } - cmd->SCp.Status = regs->fifo; eieio(); - cmd->SCp.Message = regs->fifo; eieio(); - cmd->result = - regs->command = CMD_ACCEPT_MSG; + cmd->SCp.Status = readb(®s->fifo); + cmd->SCp.Message = readb(®s->fifo); + cmd->result = CMD_ACCEPT_MSG; + writeb(CMD_ACCEPT_MSG, ®s->command); state->phase = busfreeing; break; case busfreeing: @@ -495,8 +345,7 @@ mac53c94_interrupt(int irq, void *dev_id, struct pt_regs *ptregs) } } -static void -cmd_done(struct fsc_state *state, int result) +static void cmd_done(struct fsc_state *state, int result) { Scsi_Cmnd *cmd; @@ -513,8 +362,7 @@ cmd_done(struct fsc_state *state, int result) /* * Set up DMA commands for transferring data. */ -static void -set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd) +static void set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd) { int i, dma_cmd, total; struct scatterlist *scl; @@ -523,7 +371,8 @@ set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd) u32 dma_len; int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction); - dma_cmd = data_goes_out(cmd)? OUTPUT_MORE: INPUT_MORE; + dma_cmd = cmd->sc_data_direction == SCSI_DATA_WRITE? OUTPUT_MORE: + INPUT_MORE; dcmds = state->dma_cmds; if (cmd->use_sg > 0) { int nseg; @@ -562,63 +411,9 @@ set_dma_cmds(struct fsc_state *state, Scsi_Cmnd *cmd) cmd->SCp.this_residual = total; } -/* - * Work out whether data will be going out from the host adaptor or into it. - */ -static int -data_goes_out(Scsi_Cmnd *cmd) -{ - switch (cmd->sc_data_direction) { - case SCSI_DATA_WRITE: - return 1; - case SCSI_DATA_READ: - return 0; - } - - /* for SCSI_DATA_UNKNOWN or SCSI_DATA_NONE, fall back on the - old method for now... */ - switch (cmd->cmnd[0]) { - case CHANGE_DEFINITION: - case COMPARE: - case COPY: - case COPY_VERIFY: - case FORMAT_UNIT: - case LOG_SELECT: - case MEDIUM_SCAN: - case MODE_SELECT: - case MODE_SELECT_10: - case REASSIGN_BLOCKS: - case RESERVE: - case SEARCH_EQUAL: - case SEARCH_EQUAL_12: - case SEARCH_HIGH: - case SEARCH_HIGH_12: - case SEARCH_LOW: - case SEARCH_LOW_12: - case SEND_DIAGNOSTIC: - case SEND_VOLUME_TAG: - case SET_WINDOW: - case UPDATE_BLOCK: - case WRITE_BUFFER: - case WRITE_6: - case WRITE_10: - case WRITE_12: - case WRITE_LONG: - case WRITE_LONG_2: /* alternate code for WRITE_LONG */ - case WRITE_SAME: - case WRITE_VERIFY: - case WRITE_VERIFY_12: - return 1; - default: - return 0; - } -} - -static Scsi_Host_Template driver_template = { +static Scsi_Host_Template mac53c94_template = { .proc_name = "53c94", .name = "53C94", - .detect = mac53c94_detect, - .release = mac53c94_release, .queuecommand = mac53c94_queue, .eh_abort_handler = mac53c94_abort, .eh_host_reset_handler = mac53c94_host_reset, @@ -629,4 +424,158 @@ static Scsi_Host_Template driver_template = { .use_clustering = DISABLE_CLUSTERING, }; -#include "scsi_module.c" +static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match) +{ + struct device_node *node = macio_get_of_node(mdev); + struct pci_dev *pdev = macio_get_pci_dev(mdev); + struct fsc_state *state; + struct Scsi_Host *host; + void *dma_cmd_space; + unsigned char *clkprop; + int proplen; + + if (macio_resource_count(mdev) != 2 || macio_irq_count(mdev) != 2) { + printk(KERN_ERR "mac53c94: expected 2 addrs and intrs (got %d/%d)\n", + node->n_addrs, node->n_intrs); + return -ENODEV; + } + + if (macio_request_resources(mdev, "mac53c94") != 0) { + printk(KERN_ERR "mac53c94: unable to request memory resources"); + return -EBUSY; + } + + host = scsi_host_alloc(&mac53c94_template, sizeof(struct fsc_state)); + if (host == NULL) { + printk(KERN_ERR "mac53c94: couldn't register host"); + goto out_release; + } + + state = (struct fsc_state *) host->hostdata; + macio_set_drvdata(mdev, state); + state->host = host; + state->pdev = pdev; + state->mdev = mdev; + + state->regs = (struct mac53c94_regs *) + ioremap(macio_resource_start(mdev, 0), 0x1000); + state->intr = macio_irq(mdev, 0); + state->dma = (struct dbdma_regs *) + ioremap(macio_resource_start(mdev, 1), 0x1000); + state->dmaintr = macio_irq(mdev, 1); + if (state->regs == NULL || state->dma == NULL) { + printk(KERN_ERR "mac53c94: ioremap failed for %s\n", + node->full_name); + goto out_free; + } + + clkprop = get_property(node, "clock-frequency", &proplen); + if (clkprop == NULL || proplen != sizeof(int)) { + printk(KERN_ERR "%s: can't get clock frequency, " + "assuming 25MHz\n", node->full_name); + state->clk_freq = 25000000; + } else + state->clk_freq = *(int *)clkprop; + + /* Space for dma command list: +1 for stop command, + * +1 to allow for aligning. + * XXX FIXME: Use DMA consistent routines + */ + dma_cmd_space = kmalloc((host->sg_tablesize + 2) * + sizeof(struct dbdma_cmd), GFP_KERNEL); + if (dma_cmd_space == 0) { + printk(KERN_ERR "mac53c94: couldn't allocate dma " + "command space for %s\n", node->full_name); + goto out_free; + } + state->dma_cmds = (struct dbdma_cmd *)DBDMA_ALIGN(dma_cmd_space); + memset(state->dma_cmds, 0, (host->sg_tablesize + 1) + * sizeof(struct dbdma_cmd)); + state->dma_cmd_space = dma_cmd_space; + + mac53c94_init(state); + + if (request_irq(state->intr, do_mac53c94_interrupt, 0, "53C94", state)) { + printk(KERN_ERR "mac53C94: can't get irq %d for %s\n", + state->intr, node->full_name); + goto out_free_dma; + } + + /* XXX FIXME: handle failure */ + scsi_add_host(host, &mdev->ofdev.dev); + scsi_scan_host(host); + + return 0; + + out_free_dma: + kfree(state->dma_cmd_space); + out_free: + if (state->dma != NULL) + iounmap(state->dma); + if (state->regs != NULL) + iounmap(state->regs); + scsi_host_put(host); + out_release: + macio_release_resources(mdev); + + return -ENODEV; +} + +static int mac53c94_remove(struct macio_dev *mdev) +{ + struct fsc_state *fp = (struct fsc_state *)macio_get_drvdata(mdev); + struct Scsi_Host *host = fp->host; + + scsi_remove_host(host); + + free_irq(fp->intr, fp); + + if (fp->regs) + iounmap((void *) fp->regs); + if (fp->dma) + iounmap((void *) fp->dma); + kfree(fp->dma_cmd_space); + + scsi_host_put(host); + + macio_release_resources(mdev); + + return 0; +} + + +static struct of_match mac53c94_match[] = +{ + { + .name = "53c94", + .type = OF_ANY_MATCH, + .compatible = OF_ANY_MATCH + }, + {}, +}; + +static struct macio_driver mac53c94_driver = +{ + .name = "mac53c94", + .match_table = mac53c94_match, + .probe = mac53c94_probe, + .remove = mac53c94_remove, +}; + + +static int __init init_mac53c94(void) +{ + return macio_register_driver(&mac53c94_driver); +} + +static void __exit exit_mac53c94(void) +{ + return macio_unregister_driver(&mac53c94_driver); +} + +module_init(init_mac53c94); +module_exit(exit_mac53c94); + +MODULE_DESCRIPTION("PowerMac 53c94 SCSI driver"); +MODULE_AUTHOR("Paul Mackerras "); +MODULE_LICENSE("GPL"); -- 2.53.0