X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Ffdomain.c;h=5d4ea6f77953f2fdeabf19d22eba31551bc2fae6;hb=refs%2Fheads%2Fvserver;hp=7b53d006c9b5cccfd771a13f8f51c12571b994c4;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 7b53d006c..5d4ea6f77 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -266,7 +266,6 @@ **************************************************************************/ -#include #include #include #include @@ -279,12 +278,17 @@ #include #include #include +#include +#include -#include #include -#include "scsi.h" -#include "hosts.h" +#include +#include +#include +#include +#include +#include "fdomain.h" MODULE_AUTHOR("Rickard E. Faith"); MODULE_DESCRIPTION("Future domain SCSI driver"); @@ -379,13 +383,15 @@ enum out_port_type { /* .bss will zero all the static variables below */ static int port_base; static unsigned long bios_base; +static void __iomem * bios_mem; static int bios_major; static int bios_minor; static int PCI_bus; +static struct pci_dev *PCI_dev; static int Quantum; /* Quantum board variant */ static int interrupt_level; static volatile int in_command; -static Scsi_Cmnd *current_SC; +static struct scsi_cmnd *current_SC; static enum chip_type chip = unknown; static int adapter_mask; static int this_id; @@ -395,31 +401,14 @@ static int setup_called; static volatile int in_interrupt_flag; #endif -static int SCSI_Mode_Cntl_port; -static int FIFO_Data_Count_port; -static int Interrupt_Cntl_port; -static int Interrupt_Status_port; -static int Read_FIFO_port; -static int Read_SCSI_Data_port; -static int SCSI_Cntl_port; -static int SCSI_Data_NoACK_port; -static int SCSI_Status_port; -static int TMC_Cntl_port; -static int TMC_Status_port; -static int Write_FIFO_port; -static int Write_SCSI_Data_port; - static int FIFO_Size = 0x2000; /* 8k FIFO for pre-tmc18c30 chips */ -static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id, - struct pt_regs * regs ); -int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt); - +static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id ); /* Allow insmod parameters to be like LILO parameters. For example: insmod fdomain fdomain=0x140,11 */ static char * fdomain = NULL; -MODULE_PARM(fdomain, "s"); +module_param(fdomain, charp, 0); static unsigned long addresses[] = { 0xc8000, @@ -430,10 +419,10 @@ static unsigned long addresses[] = { 0xd0000, 0xe0000, }; -#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned )) - +#define ADDRESS_COUNT ARRAY_SIZE(addresses) + static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 }; -#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short )) +#define PORT_COUNT ARRAY_SIZE(ports) static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 }; @@ -469,7 +458,7 @@ static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 }; */ -struct signature { +static struct signature { const char *signature; int sig_offset; int sig_length; @@ -512,7 +501,7 @@ struct signature { geometry location are verified). */ }; -#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature )) +#define SIGNATURE_COUNT ARRAY_SIZE(signatures) static void print_banner( struct Scsi_Host *shpnt ) { @@ -529,7 +518,7 @@ static void print_banner( struct Scsi_Host *shpnt ) if (bios_minor >= 0) printk("%d", bios_minor); else printk("?."); - + printk( " at 0x%lx using scsi id %d\n", bios_base, shpnt->this_id ); } @@ -551,7 +540,7 @@ static void print_banner( struct Scsi_Host *shpnt ) printk( "\n" ); } -int __init fdomain_setup(char *str) +int fdomain_setup(char *str) { int ints[4]; @@ -580,14 +569,14 @@ static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */ mdelay(10*amount); } -inline static void fdomain_make_bus_idle( void ) +static inline void fdomain_make_bus_idle( void ) { - outb( 0, SCSI_Cntl_port ); - outb( 0, SCSI_Mode_Cntl_port ); + outb(0, port_base + SCSI_Cntl); + outb(0, port_base + SCSI_Mode_Cntl); if (chip == tmc18c50 || chip == tmc18c30) - outb( 0x21 | PARITY_MASK, TMC_Cntl_port ); /* Clear forced intr. */ + outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear forced intr. */ else - outb( 0x01 | PARITY_MASK, TMC_Cntl_port ); + outb(0x01 | PARITY_MASK, port_base + TMC_Cntl); } static int fdomain_is_valid_port( int port ) @@ -678,6 +667,7 @@ static int fdomain_get_irq( int base ) static int fdomain_isa_detect( int *irq, int *iobase ) { +#ifndef PCMCIA int i, j; int base = 0xdeadbeef; int flag = 0; @@ -686,12 +676,15 @@ static int fdomain_isa_detect( int *irq, int *iobase ) printk( "scsi: fdomain_isa_detect:" ); #endif - for (i = 0; !bios_base && i < ADDRESS_COUNT; i++) { + for (i = 0; i < ADDRESS_COUNT; i++) { + void __iomem *p = ioremap(addresses[i], 0x2000); + if (!p) + continue; #if DEBUG_DETECT printk( " %lx(%lx),", addresses[i], bios_base ); #endif - for (j = 0; !bios_base && j < SIGNATURE_COUNT; j++) { - if (isa_check_signature(addresses[i] + signatures[j].sig_offset, + for (j = 0; j < SIGNATURE_COUNT; j++) { + if (check_signature(p + signatures[j].sig_offset, signatures[j].signature, signatures[j].sig_length )) { bios_major = signatures[j].major_bios_version; @@ -699,10 +692,14 @@ static int fdomain_isa_detect( int *irq, int *iobase ) PCI_bus = (signatures[j].flag == 1); Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0; bios_base = addresses[i]; + bios_mem = p; + goto found; } } + iounmap(p); } - + +found: if (bios_major == 2) { /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. Assuming the ROM is enabled (otherwise we wouldn't have been @@ -715,13 +712,13 @@ static int fdomain_isa_detect( int *irq, int *iobase ) switch (Quantum) { case 2: /* ISA_200S */ case 3: /* ISA_250MG */ - base = isa_readb(bios_base + 0x1fa2) + (isa_readb(bios_base + 0x1fa3) << 8); + base = readb(bios_mem + 0x1fa2) + (readb(bios_mem + 0x1fa3) << 8); break; case 4: /* ISA_200S (another one) */ - base = isa_readb(bios_base + 0x1fa3) + (isa_readb(bios_base + 0x1fa4) << 8); + base = readb(bios_mem + 0x1fa3) + (readb(bios_mem + 0x1fa4) << 8); break; default: - base = isa_readb(bios_base + 0x1fcc) + (isa_readb(bios_base + 0x1fcd) << 8); + base = readb(bios_mem + 0x1fcc) + (readb(bios_mem + 0x1fcd) << 8); break; } @@ -729,17 +726,20 @@ static int fdomain_isa_detect( int *irq, int *iobase ) printk( " %x,", base ); #endif - for (flag = 0, i = 0; !flag && i < PORT_COUNT; i++) { - if (base == ports[i]) - ++flag; + for (i = 0; i < PORT_COUNT; i++) { + if (base == ports[i]) { + if (!request_region(base, 0x10, "fdomain")) + break; + if (!fdomain_is_valid_port(base)) { + release_region(base, 0x10); + break; + } + *irq = fdomain_get_irq( base ); + *iobase = base; + return 1; + } } - if (flag && fdomain_is_valid_port( base )) { - *irq = fdomain_get_irq( base ); - *iobase = base; - return 1; - } - /* This is a bad sign. It usually means that someone patched the BIOS signature list (the signatures variable) to contain a BIOS signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */ @@ -760,7 +760,7 @@ static int fdomain_isa_detect( int *irq, int *iobase ) for (i = 0; i < PORT_COUNT; i++) { base = ports[i]; - if (check_region( base, 0x10 )) { + if (!request_region(base, 0x10, "fdomain")) { #if DEBUG_DETECT printk( " (%x inuse),", base ); #endif @@ -769,7 +769,10 @@ static int fdomain_isa_detect( int *irq, int *iobase ) #if DEBUG_DETECT printk( " %x,", base ); #endif - if ((flag = fdomain_is_valid_port( base ))) break; + flag = fdomain_is_valid_port(base); + if (flag) + break; + release_region(base, 0x10); } #if DEBUG_DETECT @@ -783,6 +786,9 @@ static int fdomain_isa_detect( int *irq, int *iobase ) *iobase = base; return 1; /* success */ +#else + return 0; +#endif } /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int* @@ -807,9 +813,10 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ PCI_DEVICE_ID_FD_36C70 ); #endif - if ((pdev = pci_find_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) + if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) return 0; - if (pci_enable_device(pdev)) return 0; + if (pci_enable_device(pdev)) + goto fail; #if DEBUG_DETECT printk( "scsi: TMC-3260 detect:" @@ -825,6 +832,9 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ pci_base = pci_resource_start(pdev, 0); pci_irq = pdev->irq; + if (!request_region( pci_base, 0x10, "fdomain" )) + goto fail; + /* Now we have the I/O base address and interrupt from the PCI configuration registers. */ @@ -837,22 +847,28 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base ); #endif - if (!fdomain_is_valid_port( *iobase )) { + if (!fdomain_is_valid_port(pci_base)) { printk(KERN_ERR "scsi: PCI card detected, but driver not loaded (invalid port)\n" ); - return 0; + release_region(pci_base, 0x10); + goto fail; } /* Fill in a few global variables. Ugh. */ bios_major = bios_minor = -1; PCI_bus = 1; + PCI_dev = pdev; Quantum = 0; bios_base = 0; return 1; +fail: + pci_dev_put(pdev); + return 0; } + #endif -struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) +struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) { int retcode; struct Scsi_Host *shpnt; @@ -863,10 +879,16 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) printk( "scsi: No BIOS, using port_base = 0x%x, irq = %d\n", port_base, interrupt_level ); #endif + if (!request_region(port_base, 0x10, "fdomain")) { + printk( "scsi: port 0x%x is busy\n", port_base ); + printk( "scsi: Bad LILO/INSMOD parameters?\n" ); + return NULL; + } if (!fdomain_is_valid_port( port_base )) { printk( "scsi: Cannot locate chip at port base 0x%x\n", port_base ); printk( "scsi: Bad LILO/INSMOD parameters?\n" ); + release_region(port_base, 0x10); return NULL; } } else { @@ -887,28 +909,14 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) } } - SCSI_Mode_Cntl_port = port_base + SCSI_Mode_Cntl; - FIFO_Data_Count_port = port_base + FIFO_Data_Count; - Interrupt_Cntl_port = port_base + Interrupt_Cntl; - Interrupt_Status_port = port_base + Interrupt_Status; - Read_FIFO_port = port_base + Read_FIFO; - Read_SCSI_Data_port = port_base + Read_SCSI_Data; - SCSI_Cntl_port = port_base + SCSI_Cntl; - SCSI_Data_NoACK_port = port_base + SCSI_Data_NoACK; - SCSI_Status_port = port_base + SCSI_Status; - TMC_Cntl_port = port_base + TMC_Cntl; - TMC_Status_port = port_base + TMC_Status; - Write_FIFO_port = port_base + Write_FIFO; - Write_SCSI_Data_port = port_base + Write_SCSI_Data; - - fdomain_16x0_bus_reset( NULL); + fdomain_16x0_bus_reset(NULL); if (fdomain_test_loopback()) { printk(KERN_ERR "scsi: Detection failed (loopback test failed at port base 0x%x)\n", port_base); if (setup_called) { printk(KERN_ERR "scsi: Bad LILO/INSMOD parameters?\n"); } - return NULL; + goto fail; } if (this_id) { @@ -928,23 +936,24 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) get resources. */ shpnt = scsi_register( tpnt, 0 ); - if(shpnt == NULL) + if(shpnt == NULL) { + release_region(port_base, 0x10); return NULL; + } shpnt->irq = interrupt_level; shpnt->io_port = port_base; - scsi_set_device(shpnt, &pdev->dev); shpnt->n_io_port = 0x10; print_banner( shpnt ); /* Log IRQ with kernel */ if (!interrupt_level) { printk(KERN_ERR "scsi: Card Detected, but driver not loaded (no IRQ)\n" ); - return NULL; + goto fail; } else { /* Register the IRQ with the kernel */ retcode = request_irq( interrupt_level, - do_fdomain_16x0_intr, pdev?SA_SHIRQ:0, "fdomain", shpnt); + do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt); if (retcode < 0) { if (retcode == -EINVAL) { @@ -960,17 +969,17 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) printk(KERN_ERR " Send mail to faith@acm.org\n" ); } printk(KERN_ERR "scsi: Detected, but driver not loaded (IRQ)\n" ); - return NULL; + goto fail; } } - - /* Log I/O ports with kernel */ - request_region( port_base, 0x10, "fdomain" ); - return shpnt; +fail: + pci_dev_put(pdev); + release_region(port_base, 0x10); + return NULL; } -static int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) +static int fdomain_16x0_detect(struct scsi_host_template *tpnt) { if (fdomain) fdomain_setup(fdomain); @@ -1008,13 +1017,13 @@ static int fdomain_arbitrate( void ) printk( "fdomain_arbitrate()\n" ); #endif - outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */ - outb( adapter_mask, port_base + SCSI_Data_NoACK ); /* Set our id bit */ - outb( 0x04 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */ + outb(0x00, port_base + SCSI_Cntl); /* Disable data drivers */ + outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */ + outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */ timeout = 500; do { - status = inb( TMC_Status_port ); /* Read adapter status */ + status = inb(port_base + TMC_Status); /* Read adapter status */ if (status & 0x02) /* Arbitration complete */ return 0; mdelay(1); /* Wait one millisecond */ @@ -1041,19 +1050,19 @@ static int fdomain_select( int target ) static int flag = 0; #endif - outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ - outb( adapter_mask | (1 << target), SCSI_Data_NoACK_port ); + outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */ + outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK); /* Stop arbitration and enable parity */ - outb( PARITY_MASK, TMC_Cntl_port ); + outb(PARITY_MASK, port_base + TMC_Cntl); timeout = 350; /* 350 msec */ do { - status = inb( SCSI_Status_port ); /* Read adapter status */ + status = inb(port_base + SCSI_Status); /* Read adapter status */ if (status & 1) { /* Busy asserted */ /* Enable SCSI Bus (on error, should make bus idle with 0) */ - outb( 0x80, SCSI_Cntl_port ); + outb(0x80, port_base + SCSI_Cntl); return 0; } mdelay(1); /* wait one msec */ @@ -1078,7 +1087,7 @@ static void my_done(int error) { if (in_command) { in_command = 0; - outb( 0x00, Interrupt_Cntl_port ); + outb(0x00, port_base + Interrupt_Cntl); fdomain_make_bus_idle(); current_SC->result = error; if (current_SC->scsi_done) @@ -1092,8 +1101,7 @@ static void my_done(int error) #endif } -static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, - struct pt_regs * regs ) +static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id) { unsigned long flags; int status; @@ -1107,11 +1115,11 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, running. */ /* Check for other IRQ sources */ - if((inb(TMC_Status_port)&0x01)==0) + if ((inb(port_base + TMC_Status) & 0x01) == 0) return IRQ_NONE; /* It is our IRQ */ - outb( 0x00, Interrupt_Cntl_port ); + outb(0x00, port_base + Interrupt_Cntl); /* We usually have one spurious interrupt after each command. Ignore it. */ if (!in_command || !current_SC) { /* Spurious interrupt */ @@ -1136,7 +1144,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, #endif if (current_SC->SCp.phase & in_arbitration) { - status = inb( TMC_Status_port ); /* Read adapter status */ + status = inb(port_base + TMC_Status); /* Read adapter status */ if (!(status & 0x02)) { #if EVERY_ACCESS printk( " AFAIL " ); @@ -1148,22 +1156,22 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, } current_SC->SCp.phase = in_selection; - outb( 0x40 | FIFO_COUNT, Interrupt_Cntl_port ); + outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl); - outb( 0x82, SCSI_Cntl_port ); /* Bus Enable + Select */ - outb( adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port ); + outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */ + outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK); /* Stop arbitration and enable parity */ - outb( 0x10 | PARITY_MASK, TMC_Cntl_port ); + outb(0x10 | PARITY_MASK, port_base + TMC_Cntl); #if DEBUG_RACE in_interrupt_flag = 0; #endif return IRQ_HANDLED; } else if (current_SC->SCp.phase & in_selection) { - status = inb( SCSI_Status_port ); + status = inb(port_base + SCSI_Status); if (!(status & 0x01)) { /* Try again, for slow devices */ - if (fdomain_select( current_SC->device->id )) { + if (fdomain_select( scmd_id(current_SC) )) { #if EVERY_ACCESS printk( " SFAIL " ); #endif @@ -1176,12 +1184,12 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, printk( " AltSel " ); #endif /* Stop arbitration and enable parity */ - outb( 0x10 | PARITY_MASK, TMC_Cntl_port ); + outb(0x10 | PARITY_MASK, port_base + TMC_Cntl); } } current_SC->SCp.phase = in_other; - outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port ); - outb( 0x80, SCSI_Cntl_port ); + outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl); + outb(0x80, port_base + SCSI_Cntl); #if DEBUG_RACE in_interrupt_flag = 0; #endif @@ -1190,15 +1198,15 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, /* current_SC->SCp.phase == in_other: this is the body of the routine */ - status = inb( SCSI_Status_port ); + status = inb(port_base + SCSI_Status); if (status & 0x10) { /* REQ */ switch (status & 0x0e) { case 0x08: /* COMMAND OUT */ - outb( current_SC->cmnd[current_SC->SCp.sent_command++], - Write_SCSI_Data_port ); + outb(current_SC->cmnd[current_SC->SCp.sent_command++], + port_base + Write_SCSI_Data); #if EVERY_ACCESS printk( "CMD = %x,", current_SC->cmnd[ current_SC->SCp.sent_command - 1] ); @@ -1207,17 +1215,17 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */ if (chip != tmc1800 && !current_SC->SCp.have_data_in) { current_SC->SCp.have_data_in = -1; - outb( 0xd0 | PARITY_MASK, TMC_Cntl_port ); + outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl); } break; case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */ if (chip != tmc1800 && !current_SC->SCp.have_data_in) { current_SC->SCp.have_data_in = 1; - outb( 0x90 | PARITY_MASK, TMC_Cntl_port ); + outb(0x90 | PARITY_MASK, port_base + TMC_Cntl); } break; case 0x0c: /* STATUS IN */ - current_SC->SCp.Status = inb( Read_SCSI_Data_port ); + current_SC->SCp.Status = inb(port_base + Read_SCSI_Data); #if EVERY_ACCESS printk( "Status = %x, ", current_SC->SCp.Status ); #endif @@ -1233,10 +1241,10 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, #endif break; case 0x0a: /* MESSAGE OUT */ - outb( MESSAGE_REJECT, Write_SCSI_Data_port ); /* Reject */ + outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */ break; case 0x0e: /* MESSAGE IN */ - current_SC->SCp.Message = inb( Read_SCSI_Data_port ); + current_SC->SCp.Message = inb(port_base + Read_SCSI_Data); #if EVERY_ACCESS printk( "Message = %x, ", current_SC->SCp.Message ); #endif @@ -1254,20 +1262,20 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) { - if(scsi_to_pci_dma_dir(current_SC->sc_data_direction) == PCI_DMA_TODEVICE) + if(current_SC->sc_data_direction == DMA_TO_DEVICE) { current_SC->SCp.have_data_in = -1; - outb( 0xd0 | PARITY_MASK, TMC_Cntl_port ); + outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl); } else { current_SC->SCp.have_data_in = 1; - outb( 0x90 | PARITY_MASK, TMC_Cntl_port ); + outb(0x90 | PARITY_MASK, port_base + TMC_Cntl); } } if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */ - while ( (data_count = FIFO_Size - inw( FIFO_Data_Count_port )) > 512 ) { + while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) { #if EVERY_ACCESS printk( "DC=%d, ", data_count ) ; #endif @@ -1278,11 +1286,11 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, printk( "%d OUT, ", data_count ); #endif if (data_count == 1) { - outb( *current_SC->SCp.ptr++, Write_FIFO_port ); + outb(*current_SC->SCp.ptr++, port_base + Write_FIFO); --current_SC->SCp.this_residual; } else { data_count >>= 1; - outsw( Write_FIFO_port, current_SC->SCp.ptr, data_count ); + outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count); current_SC->SCp.ptr += 2 * data_count; current_SC->SCp.this_residual -= 2 * data_count; } @@ -1300,7 +1308,7 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, } if (current_SC->SCp.have_data_in == 1) { /* DATA IN */ - while ((data_count = inw( FIFO_Data_Count_port )) > 0) { + while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) { #if EVERY_ACCESS printk( "DC=%d, ", data_count ); #endif @@ -1311,11 +1319,11 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, printk( "%d IN, ", data_count ); #endif if (data_count == 1) { - *current_SC->SCp.ptr++ = inb( Read_FIFO_port ); + *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO); --current_SC->SCp.this_residual; } else { data_count >>= 1; /* Number of words */ - insw( Read_FIFO_port, current_SC->SCp.ptr, data_count ); + insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count); current_SC->SCp.ptr += 2 * data_count; current_SC->SCp.this_residual -= 2 * data_count; } @@ -1375,10 +1383,10 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, } else { if (current_SC->SCp.phase & disconnect) { - outb( 0xd0 | FIFO_COUNT, Interrupt_Cntl_port ); - outb( 0x00, SCSI_Cntl_port ); + outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl); + outb(0x00, port_base + SCSI_Cntl); } else { - outb( 0x90 | FIFO_COUNT, Interrupt_Cntl_port ); + outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl); } } #if DEBUG_RACE @@ -1387,7 +1395,8 @@ static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id, return IRQ_HANDLED; } -static int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) +static int fdomain_16x0_queue(struct scsi_cmnd *SCpnt, + void (*done)(struct scsi_cmnd *)) { if (in_command) { panic( "scsi: fdomain_16x0_queue() NOT REENTRANT!\n" ); @@ -1428,18 +1437,18 @@ static int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) current_SC->SCp.phase = in_arbitration; /* Start arbitration */ - outb( 0x00, Interrupt_Cntl_port ); - outb( 0x00, SCSI_Cntl_port ); /* Disable data drivers */ - outb( adapter_mask, SCSI_Data_NoACK_port ); /* Set our id bit */ + outb(0x00, port_base + Interrupt_Cntl); + outb(0x00, port_base + SCSI_Cntl); /* Disable data drivers */ + outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */ ++in_command; - outb( 0x20, Interrupt_Cntl_port ); - outb( 0x14 | PARITY_MASK, TMC_Cntl_port ); /* Start arbitration */ + outb(0x20, port_base + Interrupt_Cntl); + outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */ return 0; } #if DEBUG_ABORT -static void print_info(Scsi_Cmnd *SCpnt) +static void print_info(struct scsi_cmnd *SCpnt) { unsigned int imr; unsigned int irr; @@ -1489,17 +1498,17 @@ static void print_info(Scsi_Cmnd *SCpnt) printk( " (masked)" ); printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr ); - printk( "SCSI Status = 0x%02x\n", inb( SCSI_Status_port ) ); - printk( "TMC Status = 0x%02x", inb( TMC_Status_port ) ); - if (inb( TMC_Status_port & 1)) + printk( "SCSI Status = 0x%02x\n", inb(port_base + SCSI_Status)); + printk( "TMC Status = 0x%02x", inb(port_base + TMC_Status)); + if (inb((port_base + TMC_Status) & 1)) printk( " (interrupt)" ); printk( "\n" ); - printk( "Interrupt Status = 0x%02x", inb( Interrupt_Status_port ) ); - if (inb( Interrupt_Status_port ) & 0x08) + printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status)); + if (inb(port_base + Interrupt_Status) & 0x08) printk( " (enabled)" ); printk( "\n" ); if (chip == tmc18c50 || chip == tmc18c30) { - printk( "FIFO Status = 0x%02x\n", inb( port_base + FIFO_Status ) ); + printk("FIFO Status = 0x%02x\n", inb(port_base + FIFO_Status)); printk( "Int. Condition = 0x%02x\n", inb( port_base + Interrupt_Cond ) ); } @@ -1510,7 +1519,7 @@ static void print_info(Scsi_Cmnd *SCpnt) } #endif -static int fdomain_16x0_abort( Scsi_Cmnd *SCpnt) +static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt) { #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT printk( "scsi: abort " ); @@ -1536,40 +1545,29 @@ static int fdomain_16x0_abort( Scsi_Cmnd *SCpnt) return SUCCESS; } -int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt) +int fdomain_16x0_bus_reset(struct scsi_cmnd *SCpnt) { - outb( 1, SCSI_Cntl_port ); + unsigned long flags; + + local_irq_save(flags); + + outb(1, port_base + SCSI_Cntl); do_pause( 2 ); - outb( 0, SCSI_Cntl_port ); + outb(0, port_base + SCSI_Cntl); do_pause( 115 ); - outb( 0, SCSI_Mode_Cntl_port ); - outb( PARITY_MASK, TMC_Cntl_port ); - return SUCCESS; -} + outb(0, port_base + SCSI_Mode_Cntl); + outb(PARITY_MASK, port_base + TMC_Cntl); -static int fdomain_16x0_host_reset(Scsi_Cmnd *SCpnt) -{ - return FAILED; -} - -static int fdomain_16x0_device_reset(Scsi_Cmnd *SCpnt) -{ - return FAILED; + local_irq_restore(flags); + return SUCCESS; } -#include - static int fdomain_16x0_biosparam(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int *info_array) { int drive; - unsigned char buf[512 + sizeof (Scsi_Ioctl_Command)]; - Scsi_Ioctl_Command *sic = (Scsi_Ioctl_Command *) buf; int size = capacity; - unsigned char *data = sic->data; - unsigned char do_read[] = { READ_6, 0, 0, 0, 1, 0 }; - int retcode; unsigned long offset; struct drive_info { unsigned short cylinders; @@ -1631,42 +1629,36 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev, case 2: /* ISA_200S */ /* The value of 25 has never been verified. It should probably be 15. */ - offset = bios_base + 0x1f33 + drive * 25; + offset = 0x1f33 + drive * 25; break; case 3: /* ISA_250MG */ - offset = bios_base + 0x1f36 + drive * 15; + offset = 0x1f36 + drive * 15; break; case 4: /* ISA_200S (another one) */ - offset = bios_base + 0x1f34 + drive * 15; + offset = 0x1f34 + drive * 15; break; default: - offset = bios_base + 0x1f31 + drive * 25; + offset = 0x1f31 + drive * 25; break; } - isa_memcpy_fromio( &i, offset, sizeof( struct drive_info ) ); + memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) ); info_array[0] = i.heads; info_array[1] = i.sectors; info_array[2] = i.cylinders; } else if (bios_major == 3 && bios_minor >= 0 && bios_minor < 4) { /* 3.0 and 3.2 BIOS */ - memcpy_fromio( &i, bios_base + 0x1f71 + drive * 10, + memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10, sizeof( struct drive_info ) ); info_array[0] = i.heads + 1; info_array[1] = i.sectors; info_array[2] = i.cylinders; } else { /* 3.4 BIOS (and up?) */ /* This algorithm was provided by Future Domain (much thanks!). */ + unsigned char *p = scsi_bios_ptable(bdev); - sic->inlen = 0; /* zero bytes out */ - sic->outlen = 512; /* one sector in */ - memcpy( data, do_read, sizeof( do_read ) ); - retcode = kernel_scsi_ioctl( sdev, - SCSI_IOCTL_SEND_COMMAND, - sic ); - if (!retcode /* SCSI command ok */ - && data[511] == 0xaa && data[510] == 0x55 /* Partition table valid */ - && data[0x1c2]) { /* Partition type */ + if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */ + && p[4]) { /* Partition type */ /* The partition table layout is as follows: @@ -1697,8 +1689,8 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev, Future Domain algorithm, but it seemed to be a reasonable thing to do, especially in the Linux and BSD worlds. */ - info_array[0] = data[0x1c3] + 1; /* heads */ - info_array[1] = data[0x1c4] & 0x3f; /* sectors */ + info_array[0] = p[5] + 1; /* heads */ + info_array[1] = p[6] & 0x3f; /* sectors */ } else { /* Note that this new method guarantees that there will always be @@ -1718,6 +1710,7 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev, } /* For both methods, compute the cylinders */ info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] ); + kfree(p); } return 0; @@ -1729,10 +1722,12 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt) free_irq(shpnt->irq, shpnt); if (shpnt->io_port && shpnt->n_io_port) release_region(shpnt->io_port, shpnt->n_io_port); + if (PCI_bus) + pci_dev_put(PCI_dev); return 0; } -Scsi_Host_Template fdomain_driver_template = { +struct scsi_host_template fdomain_driver_template = { .module = THIS_MODULE, .name = "fdomain", .proc_name = "fdomain", @@ -1741,8 +1736,6 @@ Scsi_Host_Template fdomain_driver_template = { .queuecommand = fdomain_16x0_queue, .eh_abort_handler = fdomain_16x0_abort, .eh_bus_reset_handler = fdomain_16x0_bus_reset, - .eh_device_reset_handler = fdomain_16x0_device_reset, - .eh_host_reset_handler = fdomain_16x0_host_reset, .bios_param = fdomain_16x0_biosparam, .release = fdomain_16x0_release, .can_queue = 1, @@ -1753,6 +1746,15 @@ Scsi_Host_Template fdomain_driver_template = { }; #ifndef PCMCIA + +static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { + { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { } +}; +MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); + #define driver_template fdomain_driver_template #include "scsi_module.c" + #endif