aha152x
Subsystems (2)
PATCH 1/1 aha152x
Hi,
attached my patch for the aha152x driver. Tested for pcmcia and not pcmcia and various devices.
changes in the aha152x driver:
- gather code that is not used by PCMCIA at the end
- move request_region for !PCMCIA case to detection
- migration to new scsi host api (remove legacy code)
- free host scribble before scsi_done
- fix error handling
- one isapnp device added to id_table
and in the pcmcia stub module:
- default to synchronous transfers
- release_region hack removed
- let core module do the scsi host api calls.
Jürgen
drivers/scsi/aha152x.c renamed from linux-2.6.2-rc2/drivers/scsi/aha152x.c +620 -567
@@ -1,6 +1,6 @@/* aha152x.c -- Adaptec AHA-152x driver * Author: Jürgen E. Fischer, [email protected] -* Copyright 1993-2000 Jürgen E. Fischer +* Copyright 1993-2004 Jürgen E. Fischer * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the
@@ -13,9 +13,17 @@* General Public License for more details. * * -* $Id: aha152x.c,v 2.6 2003/10/30 20:52:47 fischer Exp $ +* $Id: aha152x.c,v 2.7 2004/01/24 11:42:59 fischer Exp $ * * $Log: aha152x.c,v $ +* Revision 2.7 2004/01/24 11:42:59 fischer +* - gather code that is not used by PCMCIA at the end +* - move request_region for !PCMCIA case to detection +* - migration to new scsi host api (remove legacy code) +* - free host scribble before scsi_done +* - fix error handling +* - one isapnp device added to id_table +* * Revision 2.6 2003/10/30 20:52:47 fischer * - interfaces changes for kernel 2.6 * - aha152x_probe_one introduced for pcmcia stub
@@ -344,7 +352,8 @@MODULE_DESCRIPTION (AHA152X_REVID );MODULE_LICENSE ("GPL" ); -#if defined(MODULE ) && !defined(PCMCIA ) +#if !defined(PCMCIA ) +#if defined(MODULE )MODULE_PARM (io,"1-2i" );MODULE_PARM_DESC (io,"base io address of controller" );static int io[] = {0 ,0 };
@@ -398,21 +407,23 @@MODULE_PARM_DESC (aha152x1,"parameters for second controller" );static int aha152x1[] = {0 ,11 ,7 ,1 ,1 ,1 ,DELAY_DEFAULT ,0 ,DEBUG_DEFAULT };#endif /* !defined(AHA152X_DEBUG) */ -#endif /* MODULE && !PCMCIA */ +#endif /* MODULE */ #ifdef __ISAPNP__static struct isapnp_device_id id_table[]__devinitdata = { - {ISAPNP_DEVICE_SINGLE ('A' ,'D' ,'P' ,0x1505 ,'A' ,'D' ,'P' ,0x1505 ), }, + {ISAPNP_ANY_ID ,ISAPNP_ANY_ID , +ISAPNP_VENDOR ('A' ,'D' ,'P' ),ISAPNP_FUNCTION (0x1505 ),0 }, + {ISAPNP_ANY_ID ,ISAPNP_ANY_ID , +ISAPNP_VENDOR ('A' ,'D' ,'P' ),ISAPNP_FUNCTION (0x1530 ),0 }, {ISAPNP_DEVICE_SINGLE_END , } };MODULE_DEVICE_TABLE (isapnp, id_table);#endif /* ISAPNP */ -/* set by aha152x_setup according to the command line */ -static int setup_count; -static int registered_count; -static struct aha152x_setup setup[2 ]; -static struct Scsi_Host *aha152x_host[2 ]; +#endif /* !PCMCIA */ + +static int registered_count=0 ; +static struct Scsi_Host *aha152x_host[2 ] = {0 ,0 };static Scsi_Host_Template aha152x_driver_template;/*
@@ -658,7 +669,6 @@static void reset_ports (struct Scsi_Host *shpnt);static void aha152x_error (struct Scsi_Host *shpnt,char *msg);static void done (struct Scsi_Host *shpnt,int error); -static int checksetup (struct aha152x_setup *setup);/* diagnostics */ static void disp_ports (struct Scsi_Host *shpnt);
@@ -666,66 +676,6 @@static void show_queues (struct Scsi_Host *shpnt);static void disp_enintr (struct Scsi_Host *shpnt); -/* possible i/o addresses for the AIC-6260; default first */ -static unsigned short ports[] = {0x340 ,0x140 }; - -#if !defined(SKIP_BIOSTEST ) -/* possible locations for the Adaptec BIOS; defaults first */ -static unsigned int addresses[] = -{ -0xdc000 ,/* default first */ -0xc8000 , -0xcc000 , -0xd0000 , -0xd4000 , -0xd8000 , -0xe0000 , -0xeb800 ,/* VTech Platinum SMP */ -0xf0000 , -}; - -/* signatures for various AIC-6[23]60 based controllers. -The point in detecting signatures is to avoid useless and maybe -harmful probes on ports. I'm not sure that all listed boards pass -auto-configuration. For those which fail the BIOS signature is -obsolete, because user intervention to supply the configuration is -needed anyway. May be an information whether or not the BIOS supports -extended translation could be also useful here. */ -static struct signature { -unsigned char *signature; -int sig_offset; -int sig_length; -} signatures[] = -{ - {"Adaptec AHA-1520 BIOS" ,0x102e ,21 }, -/* Adaptec 152x */ - {"Adaptec AHA-1520B" ,0x000b ,17 }, -/* Adaptec 152x rev B */ - {"Adaptec AHA-1520B" ,0x0026 ,17 }, -/* Iomega Jaz Jet ISA (AIC6370Q) */ - {"Adaptec ASW-B626 BIOS" ,0x1029 ,21 }, -/* on-board controller */ - {"Adaptec BIOS: ASW-B626" ,0x000f ,22 }, -/* on-board controller */ - {"Adaptec ASW-B626 S2" ,0x2e6c ,19 }, -/* on-board controller */ - {"Adaptec BIOS:AIC-6360" ,0x000c ,21 }, -/* on-board controller */ - {"ScsiPro SP-360 BIOS" ,0x2873 ,19 }, -/* ScsiPro-Controller */ - {"GA-400 LOCAL BUS SCSI BIOS" ,0x102e ,26 }, -/* Gigabyte Local-Bus-SCSI */ - {"Adaptec BIOS:AVA-282X" ,0x000c ,21 }, -/* Adaptec 282x */ - {"Adaptec IBM Dock II SCSI" ,0x2edd ,24 }, -/* IBM Thinkpad Dock II */ - {"Adaptec BIOS:AHA-1532P" ,0x001c ,22 }, -/* IBM Thinkpad Dock II SCSI */ - {"DTC3520A Host Adapter BIOS" ,0x318a ,26 }, -/* DTC 3520A ISA SCSI */ -}; -#endif -/* * queue services:
@@ -799,141 +749,6 @@return ptr; } -#if defined(PCMCIA ) || !defined(MODULE ) -static void aha152x_setup (char *str,int *ints) -{ -if (setup_count>=ARRAY_SIZE (setup)) { -printk (KERN_ERR "aha152x: you can only configure up to two controllers\n" ); -return ; - } - - setup[setup_count].conf = str; - setup[setup_count].io_port = ints[0 ] >=1 ? ints[1 ] :0x340 ; - setup[setup_count].irq = ints[0 ] >=2 ? ints[2 ] :11 ; - setup[setup_count].scsiid = ints[0 ] >=3 ? ints[3 ] :7 ; - setup[setup_count].reconnect = ints[0 ] >=4 ? ints[4 ] :1 ; - setup[setup_count].parity = ints[0 ] >=5 ? ints[5 ] :1 ; - setup[setup_count].synchronous = ints[0 ] >=6 ? ints[6 ] :1 ; - setup[setup_count].delay = ints[0 ] >=7 ? ints[7 ] :DELAY_DEFAULT ; - setup[setup_count].ext_trans = ints[0 ] >=8 ? ints[8 ] :0 ; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug = ints[0 ] >=9 ? ints[9 ] :DEBUG_DEFAULT ; -if (ints[0 ] >9 ) { -printk (KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" -"[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n" ); -#else -if (ints[0 ] >8 ) {/*}*/ -printk (KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" -"[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n" ); -#endif - }else { - setup_count++; - } -} -#endif - -#if !defined(MODULE ) -static int __init do_setup (char *str) -{ - -#if defined(AHA152X_DEBUG ) -int ints[11 ]; -#else -int ints[10 ]; -#endif -int count=setup_count; - -get_options (str,ARRAY_SIZE (ints), ints); -aha152x_setup (str,ints); - -return count<setup_count; -} - -__setup ("aha152x=" , do_setup); -#endif - -/* -* Test, if port_base is valid. -* -*/ -static int aha152x_porttest (int io_port) -{ -int i; - -SETPORT (io_port +O_DMACNTRL1 ,0 );/* reset stack pointer */ -for (i =0 ; i <16 ; i++) -SETPORT (io_port +O_STACK , i); - -SETPORT (io_port +O_DMACNTRL1 ,0 );/* reset stack pointer */ -for (i =0 ; i <16 &&GETPORT (io_port +O_STACK ) == i; i++) - ; - -return (i ==16 ); -} - -static int tc1550_porttest (int io_port) -{ -int i; - -SETPORT (io_port +O_TC_DMACNTRL1 ,0 );/* reset stack pointer */ -for (i =0 ; i <16 ; i++) -SETPORT (io_port +O_STACK , i); - -SETPORT (io_port +O_TC_DMACNTRL1 ,0 );/* reset stack pointer */ -for (i =0 ; i <16 &&GETPORT (io_port +O_TC_STACK ) == i; i++) - ; - -return (i ==16 ); -} - -static int checksetup (struct aha152x_setup *setup) -{ - -#if !defined(PCMCIA ) -int i; -for (i =0 ; i <ARRAY_SIZE (ports) && (setup->io_port != ports[i]); i++) - ; - -if (i ==ARRAY_SIZE (ports)) -return 0 ; -#endif -if (!request_region (setup->io_port,IO_RANGE ,"aha152x" )) -return 0 ; - -if (aha152x_porttest (setup->io_port)) { - setup->tc1550=0 ; - }else if (tc1550_porttest (setup->io_port)) { - setup->tc1550=1 ; - }else { -release_region (setup->io_port,IO_RANGE ); -return 0 ; - } - -release_region (setup->io_port,IO_RANGE ); - - -if ((setup->irq <IRQ_MIN ) || (setup->irq >IRQ_MAX )) -return 0 ; - -if ((setup->scsiid <0 ) || (setup->scsiid >7 )) -return 0 ; - -if ((setup->reconnect <0 ) || (setup->reconnect >1 )) -return 0 ; - -if ((setup->parity <0 ) || (setup->parity >1 )) -return 0 ; - -if ((setup->synchronous <0 ) || (setup->synchronous >1 )) -return 0 ; - -if ((setup->ext_trans <0 ) || (setup->ext_trans >1 )) -return 0 ; - - -return 1 ; -} -static inline struct Scsi_Host *lookup_irq (int irqno) {int i;
@@ -950,7 +765,6 @@struct Scsi_Host *shpnt =lookup_irq (irqno);if (!shpnt) { -/* no point using HOSTNO here! */ printk (KERN_ERR "aha152x: catched software interrupt %d for unknown controller.\n" , irqno);return IRQ_NONE ; }
@@ -961,17 +775,19 @@return IRQ_HANDLED ; } -struct Scsi_Host *aha152x_probe_one (struct aha152x_setup *setup) {struct Scsi_Host *shpnt; shpnt =scsi_host_alloc (&aha152x_driver_template,sizeof (struct aha152x_hostdata ));if (!shpnt) { -printk (KERN_ERR "aha152x: scsi_register failed\n" ); +printk (KERN_ERR "aha152x: scsi_host_alloc failed\n" );return NULL ; } +/* need to have host registered before triggering any interrupt */ + aha152x_host[registered_count] = shpnt; +memset (HOSTDATA (shpnt),0 ,sizeof *HOSTDATA (shpnt)); shpnt->io_port = setup->io_port;
@@ -1034,24 +850,19 @@DELAY , EXT_TRANS ? "enabled" : "disabled"); -if (!request_region (shpnt->io_port,IO_RANGE ,"aha152x" )) - goto out_unregister; -/* not expecting any interrupts */ SETPORT (SIMODE0 ,0 );SETPORT (SIMODE1 ,0 ); -if (request_irq (shpnt->irq, swintr,SA_INTERRUPT |SA_SHIRQ ,"aha152x" , shpnt) <0 ) { -printk (KERN_ERR "aha152x%d: driver needs an IRQ.\n" , shpnt->host_no); - goto out_release_region; +if (request_irq (shpnt->irq, swintr,SA_INTERRUPT |SA_SHIRQ ,"aha152x" , shpnt) ) { +printk (KERN_ERR "aha152x%d: irq %d busy.\n" , shpnt->host_no, shpnt->irq); + goto out_host_put; }HOSTDATA (shpnt)->swint =0 ;printk (KERN_INFO "aha152x%d: trying software interrupt, " , shpnt->host_no); -/* need to have host registered before triggering any interrupt */ - aha152x_host[registered_count] = shpnt;mb ();SETPORT (DMACNTRL0 ,SWINT |INTEN );mdelay (1000 );
@@ -1066,9 +877,9 @@SETPORT (DMACNTRL0 ,INTEN ); -printk (KERN_ERR "aha152x%d: IRQ %d possibly wrong. " +printk (KERN_ERR "aha152x%d: irq %d possibly wrong. " "Please verify.\n" , shpnt->host_no, shpnt->irq); - goto out_unregister_host; + goto out_host_put; }printk ("ok.\n" );
@@ -1077,322 +888,50 @@SETPORT (SSTAT0 ,0x7f );SETPORT (SSTAT1 ,0xef ); -if (request_irq (shpnt->irq, intr,SA_INTERRUPT |SA_SHIRQ ,"aha152x" , shpnt) <0 ) { -printk (KERN_ERR "aha152x%d: failed to reassign interrupt.\n" , shpnt->host_no); - goto out_unregister_host; - } - -scsi_add_host (shpnt,0 ); -scsi_scan_host (shpnt); -return shpnt;/* the pcmcia stub needs the return value; */ - -out_unregister_host: - aha152x_host[registered_count] =NULL ; -out_release_region: -release_region (shpnt->io_port,IO_RANGE ); -out_unregister: -scsi_host_put (shpnt); -return NULL ; -} - -static int __init aha152x_init (void ) -{ -int i, j, ok; -#if defined(AUTOCONF ) -aha152x_config conf; -#endif -#ifdef __ISAPNP__ -struct pnp_dev *dev=0 , *pnpdev[2 ] = {0 ,0 }; -#endif - -if (setup_count) { -printk (KERN_INFO "aha152x: processing commandline: " ); - -for (i =0 ; i < setup_count; i++) -if (!checksetup (&setup[i])) { -printk (KERN_ERR "\naha152x: %s\n" , setup[i].conf); -printk (KERN_ERR "aha152x: invalid line\n" ); - } -printk ("ok\n" ); - } - -#if defined(SETUP0 ) -if (setup_count <ARRAY_SIZE (setup)) { -struct aha152x_setup override =SETUP0 ; - -if (setup_count ==0 || (override.io_port != setup[0 ].io_port)) { -if (!checksetup (&override)) { -printk (KERN_ERR "\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n" , - override.io_port, - override.irq, - override.scsiid, - override.reconnect, - override.parity, - override.synchronous, - override.delay, - override.ext_trans); - }else - setup[setup_count++] = override; - } - } -#endif - -#if defined(SETUP1 ) -if (setup_count <ARRAY_SIZE (setup)) { -struct aha152x_setup override =SETUP1 ; - -if (setup_count ==0 || (override.io_port != setup[0 ].io_port)) { -if (!checksetup (&override)) { -printk (KERN_ERR "\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n" , - override.io_port, - override.irq, - override.scsiid, - override.reconnect, - override.parity, - override.synchronous, - override.delay, - override.ext_trans); - }else - setup[setup_count++] = override; - } - } -#endif - -#if defined(MODULE ) && !defined(PCMCIA ) -if (setup_count<ARRAY_SIZE (setup) && (aha152x[0 ]!=0 || io[0 ]!=0 || irq[0 ]!=0 )) { -if (aha152x[0 ]!=0 ) { - setup[setup_count].conf ="" ; - setup[setup_count].io_port = aha152x[0 ]; - setup[setup_count].irq = aha152x[1 ]; - setup[setup_count].scsiid = aha152x[2 ]; - setup[setup_count].reconnect = aha152x[3 ]; - setup[setup_count].parity = aha152x[4 ]; - setup[setup_count].synchronous = aha152x[5 ]; - setup[setup_count].delay = aha152x[6 ]; - setup[setup_count].ext_trans = aha152x[7 ]; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug = aha152x[8 ]; -#endif - }else if (io[0 ]!=0 || irq[0 ]!=0 ) { -if (io[0 ]!=0 ) setup[setup_count].io_port = io[0 ]; -if (irq[0 ]!=0 ) setup[setup_count].irq = irq[0 ]; - - setup[setup_count].scsiid = scsiid[0 ]; - setup[setup_count].reconnect = reconnect[0 ]; - setup[setup_count].parity = parity[0 ]; - setup[setup_count].synchronous = sync[0 ]; - setup[setup_count].delay = delay[0 ]; - setup[setup_count].ext_trans = exttrans[0 ]; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug = debug[0 ]; -#endif - } - -if (checksetup (&setup[setup_count])) - setup_count++; -else -printk (KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n" , - setup[setup_count].io_port, - setup[setup_count].irq, - setup[setup_count].scsiid, - setup[setup_count].reconnect, - setup[setup_count].parity, - setup[setup_count].synchronous, - setup[setup_count].delay, - setup[setup_count].ext_trans); - } - -if (setup_count<ARRAY_SIZE (setup) && (aha152x1[0 ]!=0 || io[1 ]!=0 || irq[1 ]!=0 )) { -if (aha152x1[0 ]!=0 ) { - setup[setup_count].conf ="" ; - setup[setup_count].io_port = aha152x1[0 ]; - setup[setup_count].irq = aha152x1[1 ]; - setup[setup_count].scsiid = aha152x1[2 ]; - setup[setup_count].reconnect = aha152x1[3 ]; - setup[setup_count].parity = aha152x1[4 ]; - setup[setup_count].synchronous = aha152x1[5 ]; - setup[setup_count].delay = aha152x1[6 ]; - setup[setup_count].ext_trans = aha152x1[7 ]; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug = aha152x1[8 ]; -#endif - }else if (io[1 ]!=0 || irq[1 ]!=0 ) { -if (io[1 ]!=0 ) setup[setup_count].io_port = io[1 ]; -if (irq[1 ]!=0 ) setup[setup_count].irq = irq[1 ]; - - setup[setup_count].scsiid = scsiid[1 ]; - setup[setup_count].reconnect = reconnect[1 ]; - setup[setup_count].parity = parity[1 ]; - setup[setup_count].synchronous = sync[1 ]; - setup[setup_count].delay = delay[1 ]; - setup[setup_count].ext_trans = exttrans[1 ]; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug = debug[1 ]; -#endif - } -if (checksetup (&setup[setup_count])) - setup_count++; -else -printk (KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n" , - setup[setup_count].io_port, - setup[setup_count].irq, - setup[setup_count].scsiid, - setup[setup_count].reconnect, - setup[setup_count].parity, - setup[setup_count].synchronous, - setup[setup_count].delay, - setup[setup_count].ext_trans); +if (request_irq (shpnt->irq, intr,SA_INTERRUPT |SA_SHIRQ ,"aha152x" , shpnt) ) { +printk (KERN_ERR "aha152x%d: failed to reassign irq %d.\n" , shpnt->host_no, shpnt->irq); + goto out_host_put; } -#endif -#ifdef __ISAPNP__ -while ( setup_count<ARRAY_SIZE (setup) && (dev=pnp_find_dev (NULL ,ISAPNP_VENDOR ('A' ,'D' ,'P' ),ISAPNP_FUNCTION (0x1505 ), dev)) ) { -if (pnp_device_attach (dev) <0 ) -continue ; -if (pnp_activate_dev (dev) <0 ) { -pnp_device_detach (dev); -continue ; - } -if (!pnp_port_valid (dev,0 )) { -pnp_device_detach (dev); -continue ; - } -if (setup_count==1 &&pnp_port_start (dev,0 )==setup[0 ].io_port) { -pnp_device_detach (dev); -continue ; - } - setup[setup_count].io_port =pnp_port_start (dev,0 ); - setup[setup_count].irq =pnp_irq (dev,0 ); - setup[setup_count].scsiid =7 ; - setup[setup_count].reconnect =1 ; - setup[setup_count].parity =1 ; - setup[setup_count].synchronous =1 ; - setup[setup_count].delay =DELAY_DEFAULT ; - setup[setup_count].ext_trans =0 ; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug =DEBUG_DEFAULT ; -#endif - pnpdev[setup_count] = dev; -printk (KERN_INFO -"aha152x: found ISAPnP AVA-1505A at io=0x%03x, irq=%d\n" , - setup[setup_count].io_port, setup[setup_count].irq); - setup_count++; +if (scsi_add_host (shpnt,0 ) ) { +free_irq (shpnt->irq, shpnt); +printk (KERN_ERR "aha152x%d: failed to add host.\n" , shpnt->host_no); + goto out_host_put; } -#endif - -#if defined(AUTOCONF ) -if (setup_count<ARRAY_SIZE (setup)) { -#if !defined(SKIP_BIOSTEST ) - ok =0 ; -for (i =0 ; i <ARRAY_SIZE (addresses) && !ok; i++) -for (j =0 ; j<ARRAY_SIZE (signatures) && !ok; j++) - ok =isa_check_signature (addresses[i] + signatures[j].sig_offset, - signatures[j].signature, signatures[j].sig_length); - -if (!ok && setup_count ==0 ) -return 0 ; - -printk (KERN_INFO "aha152x: BIOS test: passed, " ); -#else -printk (KERN_INFO "aha152x: " ); -#endif /* !SKIP_BIOSTEST */ - - ok =0 ; -for (i =0 ; i <ARRAY_SIZE (ports) && setup_count <2 ; i++) { -if ((setup_count ==1 ) && (setup[0 ].io_port == ports[i])) -continue ; - -if (aha152x_porttest (ports[i])) { - ok++; - setup[setup_count].io_port = ports[i]; - setup[setup_count].tc1550 =0 ; - - conf.cf_port = - (GETPORT (ports[i] +O_PORTA ) <<8 ) +GETPORT (ports[i] +O_PORTB ); - setup[setup_count].irq =IRQ_MIN + conf.cf_irq; - setup[setup_count].scsiid = conf.cf_id; - setup[setup_count].reconnect = conf.cf_tardisc; - setup[setup_count].parity = !conf.cf_parity; - setup[setup_count].synchronous = conf.cf_syncneg; - setup[setup_count].delay =DELAY_DEFAULT ; - setup[setup_count].ext_trans =0 ; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug =DEBUG_DEFAULT ; -#endif - setup_count++; - }else if (tc1550_porttest (ports[i])) { - ok++; - setup[setup_count].io_port = ports[i]; - setup[setup_count].tc1550 =1 ; - - conf.cf_port = - (GETPORT (ports[i] +O_PORTA ) <<8 ) +GETPORT (ports[i] +O_PORTB ); - - setup[setup_count].irq =IRQ_MIN + conf.cf_irq; - setup[setup_count].scsiid = conf.cf_id; - setup[setup_count].reconnect = conf.cf_tardisc; - setup[setup_count].parity = !conf.cf_parity; - setup[setup_count].synchronous = conf.cf_syncneg; - setup[setup_count].delay =DELAY_DEFAULT ; - setup[setup_count].ext_trans =0 ; -#if defined(AHA152X_DEBUG ) - setup[setup_count].debug =DEBUG_DEFAULT ; -#endif - setup_count++; - } - } +scsi_scan_host (shpnt); -if (ok) -printk ("auto configuration: ok, " ); - } -#endif + registered_count++; -printk ("detected %d controller(s)\n" , setup_count); +return shpnt; -for (i=0 ; i<setup_count; i++) { -aha152x_probe_one (&setup[i]); -if (aha152x_host[registered_count]) { -#ifdef __ISAPNP__ -if (pnpdev[i]) -HOSTDATA (aha152x_host[registered_count])->pnpdev=pnpdev[i]; -#endif - registered_count++; - } - } +out_host_put: + aha152x_host[registered_count]=0 ; +scsi_host_put (shpnt); -return registered_count>0 ; +return 0 ; } -static int aha152x_release (struct Scsi_Host *shpnt) +void aha152x_release (struct Scsi_Host *shpnt) { +if (!shpnt) +return ; +if (shpnt->irq)free_irq (shpnt->irq, shpnt); +#if !defined(PCMCIA )if (shpnt->io_port)release_region (shpnt->io_port,IO_RANGE ); +#endif #ifdef __ISAPNP__if (HOSTDATA (shpnt)->pnpdev)pnp_device_detach (HOSTDATA (shpnt)->pnpdev);#endif +scsi_remove_host (shpnt);scsi_host_put (shpnt); - -return 0 ; -} - -static void __exit aha152x_exit(void) -{ -int i; - -for (i=0 ; i<ARRAY_SIZE (setup); i++) { -if (aha152x_host[i]) { -scsi_remove_host (aha152x_host[i]); -aha152x_release (aha152x_host[i]); - aha152x_host[i]=0 ; - } - } }
@@ -1446,8 +985,8 @@#if defined(AHA152X_DEBUG )if (HOSTDATA (shpnt)->debug & debug_queue) { -printk (INFO_LEAD "queue: cmd_len=%d pieces=%d size=%u cmnd=" , -CMDINFO (SCpnt), SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen); +printk (INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u cmnd=" , +CMDINFO (SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);print_command (SCpnt->cmnd); }#endif
@@ -1466,7 +1005,7 @@return FAILED ; } }else { - SCpnt->host_scribble =kmalloc (sizeof (struct aha152x_scdata ),GFP_ATOMIC ); + SCpnt->host_scribble =kmalloc (sizeof (struct aha152x_scdata ),GFP_ATOMIC );if (SCpnt->host_scribble==0 ) {printk (ERR_LEAD "allocation failed\n" ,CMDINFO (SCpnt));return FAILED ;
@@ -1561,11 +1100,6 @@Scsi_Cmnd *ptr;unsigned long flags; -if (!shpnt) { -printk (ERR_LEAD "abort(%p): no host structure\n" ,CMDINFO (SCpnt), SCpnt); -return FAILED ; - } -#if defined(AHA152X_DEBUG )if (HOSTDATA (shpnt)->debug & debug_eh) {printk (DEBUG_LEAD "abort(%p)" ,CMDINFO (SCpnt), SCpnt);
@@ -1610,15 +1144,12 @@Scsi_Cmnd *SCp = (Scsi_Cmnd *)p;struct semaphore *sem =SCSEM (SCp);struct Scsi_Host *shpnt = SCp->device->host; +unsigned long flags;/* remove command from issue queue */ -if (remove_SC (&ISSUE_SC , SCp)) { -printk (KERN_INFO "aha152x: ABORT timed out - removed from issue queue\n" ); -kfree (SCp->host_scribble); - SCp->host_scribble=0 ; - }else { -printk (KERN_INFO "aha152x: ABORT timed out - not on issue queue\n" ); - } +DO_LOCK (flags); +remove_SC (&ISSUE_SC , SCp); +DO_UNLOCK (flags);up (sem); }
@@ -1626,15 +1157,14 @@/* * Reset a device * -* FIXME: never seen this live. might lockup... -* */ static int aha152x_device_reset (Scsi_Cmnd * SCpnt) {struct Scsi_Host *shpnt = SCpnt->device->host;DECLARE_MUTEX_LOCKED (sem);struct timer_list timer; -int ret; +int ret, issued, disconnected; +unsigned long flags;#if defined(AHA152X_DEBUG )if (HOSTDATA (shpnt)->debug & debug_eh) {
@@ -1648,13 +1178,18 @@return FAILED ; } +DO_LOCK (flags); + issued =remove_SC (&ISSUE_SC , SCpnt)==0 ; + disconnected = issued &&remove_SC (&DISCONNECTED_SC , SCpnt); +DO_UNLOCK (flags); + SCpnt->cmd_len =0 ; SCpnt->use_sg =0 ; SCpnt->request_buffer =0 ; SCpnt->request_bufflen =0 ;init_timer (&timer); - timer.data = (unsigned long ) cmd; + timer.data = (unsigned long ) SCpnt; timer.expires = jiffies +100 *HZ ;/* 10s */ timer.function = (void (*)(unsigned long )) timer_expired;
@@ -1662,18 +1197,35 @@add_timer (&timer);down (&sem);del_timer (&timer); - + SCpnt->cmd_len = SCpnt->old_cmd_len; SCpnt->use_sg = SCpnt->old_use_sg; SCpnt->request_buffer = SCpnt->buffer; SCpnt->request_bufflen = SCpnt->bufflen; +DO_LOCK (flags); +if (SCpnt->SCp.phase & resetted) { +HOSTDATA (shpnt)->commands--; +if (!HOSTDATA (shpnt)->commands) +SETPORT (PORTA ,0 ); +kfree (SCpnt->host_scribble); + SCpnt->host_scribble=0 ; + ret =SUCCESS ; }else { +/* requeue */ +if (!issued) { +append_SC (&ISSUE_SC , SCpnt); + }else if (disconnected) { +append_SC (&DISCONNECTED_SC , SCpnt); + } + ret =FAILED ; } +DO_UNLOCK (flags); +spin_lock_irq (shpnt->host_lock);return ret; }
@@ -1681,13 +1233,17 @@static void free_hard_reset_SCs (struct Scsi_Host *shpnt,Scsi_Cmnd **SCs) {Scsi_Cmnd *ptr; -unsigned long flags; - -DO_LOCK (flags); ptr=*SCs;while (ptr) { -Scsi_Cmnd *next =SCNEXT (ptr); +Scsi_Cmnd *next; + +if (SCDATA (ptr)) { + next =SCNEXT (ptr); + }else { +printk (DEBUG_LEAD "queue corrupted at %p\n" ,CMDINFO (ptr), ptr); + next =0 ; + }if (!ptr->device->soft_reset) {DPRINTK (debug_eh,DEBUG_LEAD "disconnected command %p removed\n" ,CMDINFO (ptr), ptr);
@@ -1699,8 +1255,6 @@ ptr = next; } - -DO_UNLOCK (flags); }/*
@@ -1712,6 +1266,8 @@struct Scsi_Host *shpnt = SCpnt->device->host;unsigned long flags; +DO_LOCK (flags); +#if defined(AHA152X_DEBUG )if (HOSTDATA (shpnt)->debug & debug_eh) {printk (DEBUG_LEAD "aha152x_bus_reset(%p)" ,CMDINFO (SCpnt), SCpnt);
@@ -1729,12 +1285,12 @@SETPORT (SCSISEQ ,0 );mdelay (DELAY ); -DPRINTK (debug_eh,DEBUG_LEAD "bus reset returns\n" ,CMDINFO (SCpnt)); +DPRINTK (debug_eh,DEBUG_LEAD "bus resetted\n" ,CMDINFO (SCpnt)); -DO_LOCK (flags);setup_expected_interrupts (shpnt);if (HOSTDATA (shpnt)->commands==0 )SETPORT (PORTA ,0 ); +DO_UNLOCK (flags);return SUCCESS ;
@@ -2000,6 +1556,7 @@#if defined(AHA152X_STAT ) action++;#endif +if (DONE_SC ->SCp.phase & check_condition) {#if 0 if (HOSTDATA (shpnt)->debug & debug_eh) {
@@ -2029,47 +1586,57 @@#endif if (!(DONE_SC ->SCp.Status & not_issued)) { +Scsi_Cmnd *ptr =DONE_SC ; +DONE_SC =0 ;#if 0 -DPRINTK (debug_eh,ERR_LEAD "requesting sense\n" ,CMDINFO (DONE_SC )); +DPRINTK (debug_eh,ERR_LEAD "requesting sense\n" ,CMDINFO (ptr));#endif -DONE_SC ->cmnd[0 ] =REQUEST_SENSE ; -DONE_SC ->cmnd[1 ] =0 ; -DONE_SC ->cmnd[2 ] =0 ; -DONE_SC ->cmnd[3 ] =0 ; -DONE_SC ->cmnd[4 ] =sizeof (DONE_SC ->sense_buffer); -DONE_SC ->cmnd[5 ] =0 ; -DONE_SC ->cmd_len =6 ; -DONE_SC ->use_sg =0 ; -DONE_SC ->request_buffer =DONE_SC ->sense_buffer; -DONE_SC ->request_bufflen =sizeof (DONE_SC ->sense_buffer); + ptr->cmnd[0 ] =REQUEST_SENSE ; + ptr->cmnd[1 ] =0 ; + ptr->cmnd[2 ] =0 ; + ptr->cmnd[3 ] =0 ; + ptr->cmnd[4 ] =sizeof (ptr->sense_buffer); + ptr->cmnd[5 ] =0 ; + ptr->cmd_len =6 ; + ptr->use_sg =0 ; + ptr->request_buffer = ptr->sense_buffer; + ptr->request_bufflen =sizeof (ptr->sense_buffer);DO_UNLOCK (flags); -aha152x_internal_queue (DONE_SC ,0 , check_condition,DONE_SC ->scsi_done); +aha152x_internal_queue (ptr,0 , check_condition, ptr->scsi_done);DO_LOCK (flags); - -DONE_SC =0 ; - }else {#if 0 + } else {DPRINTK (debug_eh,ERR_LEAD "command not issued - CHECK CONDITION ignored\n" ,CMDINFO (DONE_SC ));#endif } }if (DONE_SC &&DONE_SC ->scsi_done) { +#if defined(AHA152X_DEBUG ) +int hostno=DONE_SC ->device->host->host_no; +int id=DONE_SC ->device->id &0xf ; +int lun=DONE_SC ->device->lun &0x7 ; +#endif +Scsi_Cmnd *ptr =DONE_SC ; +DONE_SC =0 ; +/* turn led off, when no commands are in the driver */ HOSTDATA (shpnt)->commands--;if (!HOSTDATA (shpnt)->commands)SETPORT (PORTA ,0 );/* turn led off */ +if (ptr->scsi_done != reset_done) { +kfree (ptr->host_scribble); + ptr->host_scribble=0 ; + } +DO_UNLOCK (flags); -DPRINTK (debug_done,DEBUG_LEAD "calling scsi_done(%p)\n" ,CMDINFO (DONE_SC ),DONE_SC ); -DONE_SC ->scsi_done (DONE_SC ); -DPRINTK (debug_done,DEBUG_LEAD "scsi_done(%p) returned\n" ,CMDINFO (DONE_SC ),DONE_SC ); +DPRINTK (debug_done,DEBUG_LEAD "calling scsi_done(%p)\n" , hostno, id, lun, ptr); + ptr->scsi_done (ptr); +DPRINTK (debug_done,DEBUG_LEAD "scsi_done(%p) returned\n" , hostno, id, lun, ptr);DO_LOCK (flags); - -kfree (DONE_SC ->host_scribble); -DONE_SC ->host_scribble=0 ; }DONE_SC =0 ;
@@ -2936,11 +2503,11 @@if (!ptr->device->soft_reset) {remove_SC (&DISCONNECTED_SC , ptr); - ptr->result =DID_RESET <<16 ; - ptr->scsi_done (ptr); -kfree (ptr->host_scribble); ptr->host_scribble=0 ; + + ptr->result =DID_RESET <<16 ; + ptr->scsi_done (ptr); } ptr = next;
@@ -3382,7 +2949,11 @@printk ("aborted|" );if (ptr->SCp.phase & resetted)printk ("resetted|" ); -printk ("; next=0x%p\n" ,SCNEXT (ptr)); +if (SCDATA (ptr) ) { +printk ("; next=0x%p\n" ,SCNEXT (ptr)); + }else { +printk ("; next=(host scribble NULL)\n" ); + } }/*
@@ -3406,7 +2977,7 @@printk (KERN_DEBUG "none\n" );printk (KERN_DEBUG "disconnected_SC:\n" ); -for (ptr =DISCONNECTED_SC ; ptr; ptr =SCNEXT (ptr)) +for (ptr =DISCONNECTED_SC ; ptr; ptr =SCDATA (ptr) ?SCNEXT (ptr) :0 )show_command (ptr);disp_ports (shpnt);
@@ -3914,7 +3485,489 @@ .use_clustering = DISABLE_CLUSTERING, }; -#ifndef PCMCIA +#if !defined(PCMCIA) +static int setup_count; +static struct aha152x_setup setup[2]; + +/* possible i/o addresses for the AIC-6260; default first */ +static unsigned short ports[] = { 0x340, 0x140 }; + +#if !defined(SKIP_BIOSTEST) +/* possible locations for the Adaptec BIOS; defaults first */ +static unsigned int addresses[] = +{ + 0xdc000, /* default first */ + 0xc8000, + 0xcc000, + 0xd0000, + 0xd4000, + 0xd8000, + 0xe0000, + 0xeb800, /* VTech Platinum SMP */ + 0xf0000, +}; + +/* signatures for various AIC-6[23]60 based controllers. + The point in detecting signatures is to avoid useless and maybe + harmful probes on ports. I'm not sure that all listed boards pass + auto-configuration. For those which fail the BIOS signature is + obsolete, because user intervention to supply the configuration is + needed anyway. May be an information whether or not the BIOS supports + extended translation could be also useful here. */ +static struct signature { + unsigned char *signature; + int sig_offset; + int sig_length; +} signatures[] = +{ + { "Adaptec AHA-1520 BIOS", 0x102e, 21 }, + /* Adaptec 152x */ + { "Adaptec AHA-1520B", 0x000b, 17 }, + /* Adaptec 152x rev B */ + { "Adaptec AHA-1520B", 0x0026, 17 }, + /* Iomega Jaz Jet ISA (AIC6370Q) */ + { "Adaptec ASW-B626 BIOS", 0x1029, 21 }, + /* on-board controller */ + { "Adaptec BIOS: ASW-B626", 0x000f, 22 }, + /* on-board controller */ + { "Adaptec ASW-B626 S2", 0x2e6c, 19 }, + /* on-board controller */ + { "Adaptec BIOS:AIC-6360", 0x000c, 21 }, + /* on-board controller */ + { "ScsiPro SP-360 BIOS", 0x2873, 19 }, + /* ScsiPro-Controller */ + { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 }, + /* Gigabyte Local-Bus-SCSI */ + { "Adaptec BIOS:AVA-282X", 0x000c, 21 }, + /* Adaptec 282x */ + { "Adaptec IBM Dock II SCSI", 0x2edd, 24 }, + /* IBM Thinkpad Dock II */ + { "Adaptec BIOS:AHA-1532P", 0x001c, 22 }, + /* IBM Thinkpad Dock II SCSI */ + { "DTC3520A Host Adapter BIOS", 0x318a, 26 }, + /* DTC 3520A ISA SCSI */ +}; +#endif /* !SKIP_BIOSTEST */ + +/* + * Test, if port_base is valid. + * + */ +static int aha152x_porttest(int io_port) +{ + int i; + + SETPORT(io_port + O_DMACNTRL1, 0); /* reset stack pointer */ + for (i = 0; i < 16; i++) + SETPORT(io_port + O_STACK, i); + + SETPORT(io_port + O_DMACNTRL1, 0); /* reset stack pointer */ + for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++) + ; + + return (i == 16); +} + +static int tc1550_porttest(int io_port) +{ + int i; + + SETPORT(io_port + O_TC_DMACNTRL1, 0); /* reset stack pointer */ + for (i = 0; i < 16; i++) + SETPORT(io_port + O_STACK, i); + + SETPORT(io_port + O_TC_DMACNTRL1, 0); /* reset stack pointer */ + for (i = 0; i < 16 && GETPORT(io_port + O_TC_STACK) == i; i++) + ; + + return (i == 16); +} + + +static int checksetup(struct aha152x_setup *setup) +{ + int i; + for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++) + ; + + if (i == ARRAY_SIZE(ports)) + return 0; + + if( aha152x_porttest(setup->io_port) ) { + setup->tc1550=0; + } else if( tc1550_porttest(setup->io_port) ) { + setup->tc1550=1; + } else { + return 0; + } + + if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX)) + return 0; + + if ((setup->scsiid < 0) || (setup->scsiid > 7)) + return 0; + + if ((setup->reconnect < 0) || (setup->reconnect > 1)) + return 0; + + if ((setup->parity < 0) || (setup->parity > 1)) + return 0; + + if ((setup->synchronous < 0) || (setup->synchronous > 1)) + return 0; + + if ((setup->ext_trans < 0) || (setup->ext_trans > 1)) + return 0; + + + return 1; +} + + +static int __init aha152x_init(void) +{ + int i, j, ok; +#if defined(AUTOCONF) + aha152x_config conf; +#endif +#ifdef __ISAPNP__ + struct pnp_dev *dev=0, *pnpdev[2] = {0, 0}; +#endif + + if ( setup_count ) { + printk(KERN_INFO "aha152x: processing commandline: "); + + for (i = 0; i<setup_count; i++) { + if (!checksetup(&setup[i])) { + printk(KERN_ERR "\naha152x: %s\n", setup[i].conf); + printk(KERN_ERR "aha152x: invalid line\n"); + } + } + printk("ok\n"); + } + +#if defined(SETUP0) + if (setup_count < ARRAY_SIZE(setup)) { + struct aha152x_setup override = SETUP0; + + if (setup_count == 0 || (override.io_port != setup[0].io_port)) { + if (!checksetup(&override)) { + printk(KERN_ERR "\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n", + override.io_port, + override.irq, + override.scsiid, + override.reconnect, + override.parity, + override.synchronous, + override.delay, + override.ext_trans); + } else + setup[setup_count++] = override; + } + } +#endif + +#if defined(SETUP1) + if (setup_count < ARRAY_SIZE(setup)) { + struct aha152x_setup override = SETUP1; + + if (setup_count == 0 || (override.io_port != setup[0].io_port)) { + if (!checksetup(&override)) { + printk(KERN_ERR "\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n", + override.io_port, + override.irq, + override.scsiid, + override.reconnect, + override.parity, + override.synchronous, + override.delay, + override.ext_trans); + } else + setup[setup_count++] = override; + } + } +#endif + +#if defined(MODULE) + if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) { + if(aha152x[0]!=0) { + setup[setup_count].conf = ""; + setup[setup_count].io_port = aha152x[0]; + setup[setup_count].irq = aha152x[1]; + setup[setup_count].scsiid = aha152x[2]; + setup[setup_count].reconnect = aha152x[3]; + setup[setup_count].parity = aha152x[4]; + setup[setup_count].synchronous = aha152x[5]; + setup[setup_count].delay = aha152x[6]; + setup[setup_count].ext_trans = aha152x[7]; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = aha152x[8]; +#endif + } else if(io[0]!=0 || irq[0]!=0) { + if(io[0]!=0) setup[setup_count].io_port = io[0]; + if(irq[0]!=0) setup[setup_count].irq = irq[0]; + + setup[setup_count].scsiid = scsiid[0]; + setup[setup_count].reconnect = reconnect[0]; + setup[setup_count].parity = parity[0]; + setup[setup_count].synchronous = sync[0]; + setup[setup_count].delay = delay[0]; + setup[setup_count].ext_trans = exttrans[0]; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = debug[0]; +#endif + } + + if (checksetup(&setup[setup_count])) + setup_count++; + else + printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n", + setup[setup_count].io_port, + setup[setup_count].irq, + setup[setup_count].scsiid, + setup[setup_count].reconnect, + setup[setup_count].parity, + setup[setup_count].synchronous, + setup[setup_count].delay, + setup[setup_count].ext_trans); + } + + if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) { + if(aha152x1[0]!=0) { + setup[setup_count].conf = ""; + setup[setup_count].io_port = aha152x1[0]; + setup[setup_count].irq = aha152x1[1]; + setup[setup_count].scsiid = aha152x1[2]; + setup[setup_count].reconnect = aha152x1[3]; + setup[setup_count].parity = aha152x1[4]; + setup[setup_count].synchronous = aha152x1[5]; + setup[setup_count].delay = aha152x1[6]; + setup[setup_count].ext_trans = aha152x1[7]; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = aha152x1[8]; +#endif + } else if(io[1]!=0 || irq[1]!=0) { + if(io[1]!=0) setup[setup_count].io_port = io[1]; + if(irq[1]!=0) setup[setup_count].irq = irq[1]; + + setup[setup_count].scsiid = scsiid[1]; + setup[setup_count].reconnect = reconnect[1]; + setup[setup_count].parity = parity[1]; + setup[setup_count].synchronous = sync[1]; + setup[setup_count].delay = delay[1]; + setup[setup_count].ext_trans = exttrans[1]; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = debug[1]; +#endif + } + if (checksetup(&setup[setup_count])) + setup_count++; + else + printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n", + setup[setup_count].io_port, + setup[setup_count].irq, + setup[setup_count].scsiid, + setup[setup_count].reconnect, + setup[setup_count].parity, + setup[setup_count].synchronous, + setup[setup_count].delay, + setup[setup_count].ext_trans); + } +#endif + +#ifdef __ISAPNP__ + for(i=0; setup_count<ARRAY_SIZE(setup) && id_table[i].vendor; i++) { + while ( setup_count<ARRAY_SIZE(setup) && + (dev=pnp_find_dev(NULL, id_table[i].vendor, id_table[i].function, dev)) ) { + if (pnp_device_attach(dev) < 0) + continue; + + if (pnp_activate_dev(dev) < 0) { + pnp_device_detach(dev); + continue; + } + + if (!pnp_port_valid(dev, 0)) { + pnp_device_detach(dev); + continue; + } + + if (setup_count==1 && pnp_port_start(dev, 0)==setup[0].io_port) { + pnp_device_detach(dev); + continue; + } + + setup[setup_count].io_port = pnp_port_start(dev, 0); + setup[setup_count].irq = pnp_irq(dev, 0); + setup[setup_count].scsiid = 7; + setup[setup_count].reconnect = 1; + setup[setup_count].parity = 1; + setup[setup_count].synchronous = 1; + setup[setup_count].delay = DELAY_DEFAULT; + setup[setup_count].ext_trans = 0; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = DEBUG_DEFAULT; +#endif +#if defined(__ISAPNP__) + pnpdev[setup_count] = dev; +#endif + printk (KERN_INFO + "aha152x: found ISAPnP adapter at io=0x%03x, irq=%d\n", + setup[setup_count].io_port, setup[setup_count].irq); + setup_count++; + } + } +#endif + +#if defined(AUTOCONF) + if (setup_count<ARRAY_SIZE(setup)) { +#if !defined(SKIP_BIOSTEST) + ok = 0; + for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++) + for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++) + ok = isa_check_signature(addresses[i] + signatures[j].sig_offset, + signatures[j].signature, signatures[j].sig_length); + if (!ok && setup_count == 0) + return 0; + + printk(KERN_INFO "aha152x: BIOS test: passed, "); +#else + printk(KERN_INFO "aha152x: "); +#endif /* !SKIP_BIOSTEST */ + + ok = 0; + for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) { + if ((setup_count == 1) && (setup[0].io_port == ports[i])) + continue; + + if (aha152x_porttest(ports[i])) { + ok++; + setup[setup_count].io_port = ports[i]; + setup[setup_count].tc1550 = 0; + + conf.cf_port = + (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB); + + setup[setup_count].irq = IRQ_MIN + conf.cf_irq; + setup[setup_count].scsiid = conf.cf_id; + setup[setup_count].reconnect = conf.cf_tardisc; + setup[setup_count].parity = !conf.cf_parity; + setup[setup_count].synchronous = conf.cf_syncneg; + setup[setup_count].delay = DELAY_DEFAULT; + setup[setup_count].ext_trans = 0; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = DEBUG_DEFAULT; +#endif + setup_count++; + } else if (tc1550_porttest(ports[i])) { + ok++; + setup[setup_count].io_port = ports[i]; + setup[setup_count].tc1550 = 1; + + conf.cf_port = + (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB); + + setup[setup_count].irq = IRQ_MIN + conf.cf_irq; + setup[setup_count].scsiid = conf.cf_id; + setup[setup_count].reconnect = conf.cf_tardisc; + setup[setup_count].parity = !conf.cf_parity; + setup[setup_count].synchronous = conf.cf_syncneg; + setup[setup_count].delay = DELAY_DEFAULT; + setup[setup_count].ext_trans = 0; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = DEBUG_DEFAULT; +#endif + setup_count++; + } + } + + if (ok) + printk("auto configuration: ok, "); + } +#endif + + printk("%d controller(s) configured\n", setup_count); + + for (i=0; i<setup_count; i++) { + if ( request_region(setup[i].io_port, IO_RANGE, "aha152x") ) { + struct Scsi_Host *shpnt = aha152x_probe_one(&setup[i]); + + if( !shpnt ) { + release_region(setup[i].io_port, IO_RANGE); +#if defined(__ISAPNP__) + } else if( pnpdev[i] ) { + HOSTDATA(shpnt)->pnpdev=pnpdev[i]; + pnpdev[i]=0; +#endif + } + } else { + printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup[i].io_port); + } + +#if defined(__ISAPNP__) + if( pnpdev[i] ) + pnp_device_detach(pnpdev[i]); +#endif + } + + return registered_count>0; +} + +static void __exit aha152x_exit(void) +{ + int i; + + for(i=0; i<ARRAY_SIZE(setup); i++) { + aha152x_release(aha152x_host[i]); + aha152x_host[i]=0; + } +} + module_init(aha152x_init); module_exit(aha152x_exit); + +#if !defined(MODULE) +static int __init aha152x_setup(char *str) +{ +#if defined(AHA152X_DEBUG) + int ints[11]; +#else + int ints[10]; #endif + get_options(str, ARRAY_SIZE(ints), ints); + + if(setup_count>=ARRAY_SIZE(setup)) { + printk(KERN_ERR "aha152x: you can only configure up to two controllers\n"); + return 1; + } + + setup[setup_count].conf = str; + setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340; + setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11; + setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7; + setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1; + setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1; + setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1; + setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT; + setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0; +#if defined(AHA152X_DEBUG) + setup[setup_count].debug = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT; + if (ints[0] > 9) { + printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" + "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n"); +#else + if (ints[0] > 8) { /*}*/ + printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" + "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n"); +#endif + } else { + setup_count++; + return 0; + } + + return 1; +} +__setup("aha152x=", aha152x_setup); +#endif + +#endif /* !PCMCIA */
drivers/scsi/aha152x.h renamed from linux-2.6.2-rc2/drivers/scsi/aha152x.h +4 -3
@@ -2,14 +2,14 @@#define _AHA152X_H/* -* $Id: aha152x.h,v 2.5 2002/04/14 11:24:12 fischer Exp $ +* $Id: aha152x.h,v 2.7 2004/01/24 11:39:03 fischer Exp $ */ /* number of queueable commands (unless we support more than 1 cmd_per_lun this should do) */ #define AHA152X_MAXQUEUE 7 -#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.5 $" +#define AHA152X_REVID "Adaptec 152x SCSI driver; $Revision: 2.7 $"/* port addresses */ #define SCSISEQ (HOSTIOPORT0+0x00)/* SCSI sequence control */
@@ -331,6 +331,7 @@ };struct Scsi_Host *aha152x_probe_one (struct aha152x_setup *); -int aha152x_host_reset (struct scsi_cmnd *); +void aha152x_release (struct Scsi_Host *); +int aha152x_host_reset (Scsi_Cmnd *);#endif /* _AHA152X_H */
drivers/scsi/pcmcia/aha152x_stub.c renamed from linux-2.6.2-rc2/drivers/scsi/pcmcia/aha152x_stub.c +2 -9
@@ -78,7 +78,7 @@static int host_id =7 ;static int reconnect =1 ;static int parity =1 ; -static int synchronous =0 ; +static int synchronous =1 ;static int reset_delay =100 ;static int ext_trans =0 ;
@@ -244,9 +244,6 @@CS_CHECK (RequestIRQ,pcmcia_request_irq (handle, &link->irq));CS_CHECK (RequestConfiguration,pcmcia_request_configuration (handle, &link->conf)); -/* A bad hack... */ -release_region (link->io.BasePort1, link->io.NumPorts1); -/* Set configuration options for the aha152x driver */ memset (&s,0 ,sizeof (s)); s.conf ="PCMCIA setup" ;
@@ -266,9 +263,6 @@ goto cs_failed; } -scsi_add_host (host,NULL );/* XXX handle failure */ -scsi_scan_host (host); -sprintf (info->node.dev_name,"scsi%d" , host->host_no); link->dev = &info->node; info->host = host;
@@ -286,7 +280,7 @@ {scsi_info_t *info = link->priv; -scsi_remove_host (info->host); +aha152x_release (info->host); link->dev =NULL ;pcmcia_release_configuration (link->handle);
@@ -294,7 +288,6 @@pcmcia_release_irq (link->handle, &link->irq); link->state &= ~DEV_CONFIG ; -scsi_unregister (info->host); } static int aha152x_event(event_t event, int priority,
Quoted 8 lines · Juergen E. Fischer
Hi,
attached my patch for the aha152x driver. Tested for pcmcia and not pcmcia and various devices.
changes in the aha152x driver:
- gather code that is not used by PCMCIA at the end
- moverequest_regionfor !PCMCIA case to detection
Correct and forgive me if I am wrong, it looks like you are now poking at ports without requesting them - in *_porttest. Is it a good idea?
Guennadi
Quoted 5 lines
- migration to new scsi host api (remove legacy code)
- free host scribble beforescsi_done
- fix error handling
- one isapnp device added toid_table
Quoted 8 lines
and in the pcmcia stub module:
- default to synchronous transfers
-release_regionhack removed
- let core module do the scsi host api calls.JЭrgen
---
Guennadi Liakhovetski
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html