X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Ffdomain.c;h=a78b6f257b3df58a506efc4235232825283fa1fe;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=7b53d006c9b5cccfd771a13f8f51c12571b994c4;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 7b53d006c..a78b6f257 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -279,12 +279,17 @@ #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"); @@ -385,7 +390,7 @@ static int PCI_bus; 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; @@ -414,8 +419,6 @@ static int FIFO_Size = 0x2000; /* 8k FIFO for static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id, struct pt_regs * regs ); -int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt); - /* Allow insmod parameters to be like LILO parameters. For example: insmod fdomain fdomain=0x140,11 */ static char * fdomain = NULL; @@ -551,7 +554,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]; @@ -678,6 +681,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; @@ -729,17 +733,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 +767,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 +776,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 +793,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* @@ -825,6 +838,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" )) + return 0; + /* Now we have the I/O base address and interrupt from the PCI configuration registers. */ @@ -837,8 +853,9 @@ 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" ); + release_region(pci_base, 0x10); return 0; } @@ -852,7 +869,7 @@ static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_ } #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 +880,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 { @@ -901,13 +924,14 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) 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"); } + release_region(port_base, 0x10); return NULL; } @@ -928,8 +952,10 @@ 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); @@ -939,6 +965,7 @@ struct Scsi_Host *__fdomain_16x0_detect( Scsi_Host_Template *tpnt ) /* Log IRQ with kernel */ if (!interrupt_level) { printk(KERN_ERR "scsi: Card Detected, but driver not loaded (no IRQ)\n" ); + release_region(port_base, 0x10); return NULL; } else { /* Register the IRQ with the kernel */ @@ -960,17 +987,14 @@ 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" ); + release_region(port_base, 0x10); return NULL; } } - - /* Log I/O ports with kernel */ - request_region( port_base, 0x10, "fdomain" ); - return shpnt; } -static int fdomain_16x0_detect( Scsi_Host_Template *tpnt ) +static int fdomain_16x0_detect(struct scsi_host_template *tpnt) { if (fdomain) fdomain_setup(fdomain); @@ -1254,7 +1278,7 @@ 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 ); @@ -1387,7 +1411,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" ); @@ -1439,7 +1464,7 @@ static int fdomain_16x0_queue( Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *)) } #if DEBUG_ABORT -static void print_info(Scsi_Cmnd *SCpnt) +static void print_info(struct scsi_cmnd *SCpnt) { unsigned int imr; unsigned int irr; @@ -1510,7 +1535,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,7 +1561,7 @@ 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 ); do_pause( 2 ); @@ -1547,29 +1572,12 @@ int fdomain_16x0_bus_reset(Scsi_Cmnd *SCpnt) return SUCCESS; } -static int fdomain_16x0_host_reset(Scsi_Cmnd *SCpnt) -{ - return FAILED; -} - -static int fdomain_16x0_device_reset(Scsi_Cmnd *SCpnt) -{ - return FAILED; -} - -#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; @@ -1657,16 +1665,10 @@ static int fdomain_16x0_biosparam(struct scsi_device *sdev, 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 +1699,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 +1720,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; @@ -1732,7 +1735,7 @@ static int fdomain_16x0_release(struct Scsi_Host *shpnt) 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 +1744,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,