diff options
| -rw-r--r-- | Documentation/scsi/aic79xx.txt (renamed from drivers/scsi/aic7xxx/README.aic79xx) | 0 | ||||
| -rw-r--r-- | Documentation/scsi/aic7xxx.txt | 771 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/Kconfig.aic79xx | 95 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/Kconfig.aic7xxx (renamed from drivers/scsi/aic7xxx/Kconfig) | 88 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/README.aic7xxx | 294 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_host.h | 115 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.c | 1018 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm.h | 4 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_osm_pci.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_host.h | 116 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.c | 965 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm.h | 6 | ||||
| -rw-r--r-- | drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | 4 |
13 files changed, 1435 insertions, 2045 deletions
diff --git a/drivers/scsi/aic7xxx/README.aic79xx b/Documentation/scsi/aic79xx.txt index 3f92f1de0ccc..3f92f1de0ccc 100644 --- a/drivers/scsi/aic7xxx/README.aic79xx +++ b/Documentation/scsi/aic79xx.txt diff --git a/Documentation/scsi/aic7xxx.txt b/Documentation/scsi/aic7xxx.txt index 9088d7736074..2246ca8978eb 100644 --- a/Documentation/scsi/aic7xxx.txt +++ b/Documentation/scsi/aic7xxx.txt @@ -1,477 +1,294 @@ - AIC7xxx Driver for Linux - -Introduction ----------------------------- -The AIC7xxx SCSI driver adds support for Adaptec (http://www.adaptec.com) -SCSI controllers and chipsets. Major portions of the driver and driver -development are shared between both Linux and FreeBSD. Support for the -AIC-7xxx chipsets have been in the default Linux kernel since approximately -linux-1.1.x and fairly stable since linux-1.2.x, and are also in FreeBSD -2.1.0 or later. - - Supported cards/chipsets - ---------------------------- - Adaptec Cards - ---------------------------- - AHA-274x - AHA-274xT - AHA-274xW - AHA-284x - AHA-284xW - All PCI based cards using any of the chipsets listed under motherboard - chipsets. In general, this means *all* of the Adaptec SCSI controllers - except the ones specifically excluded later on in this document. - - Motherboard Chipsets - ---------------------------- - AIC-777x - AIC-785x - AIC-786x - AIC-787x - AIC-788x - AIC-789x - AIC-3860 - - Bus Types - ---------------------------- - W - Wide SCSI, SCSI-3, 16bit bus, 68pin connector, will also support - SCSI-1/SCSI-2 50pin devices, transfer rates up to 20MB/s. - U - Ultra SCSI, transfer rates up to 40MB/s. - U2- Ultra 2 SCSI, transfer rates up to 80MB/s. - U3- Ultra 3 SCSI, transfer rates up to 160MB/s. - D - Differential SCSI. - T - Twin Channel SCSI. Up to 14 SCSI devices. - - AHA-274x - EISA SCSI controller - AHA-284x - VLB SCSI controller - AHA-29xx - PCI SCSI controller - AHA-39xx - PCI controllers with multiple separate SCSI channels on-board. - - Not Supported Devices - ------------------------------ - Adaptec Cards - ---------------------------- - AHA-2920 (Only the cards that use the Future Domain chipset are not - supported, any 2920 cards based on Adaptec AIC chipsets, - such as the 2920C, are supported) - AAA-13x Raid Adapters - AAA-113x Raid Port Card - - Motherboard Chipsets - ---------------------------- - AIC-781x - - Bus Types - ---------------------------- - R - Raid Port busses are not supported. - - The hardware RAID devices sold by Adaptec are *NOT* supported by this - driver (and will people please stop emailing me about them, they are - a totally separate beast from the bare SCSI controllers and this driver - can not be retrofitted in any sane manner to support the hardware RAID - features on those cards - Doug Ledford). - - - People - ------------------------------ - Justin T Gibbs gibbs@plutotech.com - (BSD Driver Author) - Dan Eischen deischen@iworks.InterWorks.org - (Original Linux Driver Co-maintainer) - Dean Gehnert deang@teleport.com - (Original Linux FTP/patch maintainer) - Jess Johnson jester@frenzy.com - (AIC7xxx FAQ author) - Doug Ledford dledford@redhat.com - (Current Linux aic7xxx-5.x.x Driver/Patch/FTP maintainer) - - Special thanks go to John Aycock (aycock@cpsc.ucalgary.ca), the original - author of the driver. John has since retired from the project. Thanks - again for all his work! - - Mailing list - ------------------------------ - There is a mailing list available for users who want to track development - and converse with other users and developers. This list is for both - FreeBSD and Linux support of the AIC7xxx chipsets. - - To subscribe to the AIC7xxx mailing list send mail to the list server, - with "subscribe AIC7xxx" in the body (no Subject: required): - To: majordomo@FreeBSD.ORG - --- - subscribe AIC7xxx - - To unsubscribe from the list, send mail to the list server with: - To: majordomo@FreeBSD.ORG - --- - unsubscribe AIC7xxx - - Send regular messages and replies to: AIC7xxx@FreeBSD.ORG - - Boot Command line options - ------------------------------ - "aic7xxx=no_reset" - Eliminate the SCSI bus reset during startup. - Some SCSI devices need the initial reset that this option disables - in order to work. If you have problems at bootup, please make sure - you aren't using this option. - - "aic7xxx=reverse_scan" - Certain PCI motherboards scan for devices at - bootup by scanning from the highest numbered PCI device to the - lowest numbered PCI device, others do just the opposite and scan - from lowest to highest numbered PCI device. There is no reliable - way to autodetect this ordering. So, we default to the most common - order, which is lowest to highest. Then, in case your motherboard - scans from highest to lowest, we have this option. If your BIOS - finds the drives on controller A before controller B but the linux - kernel finds your drives on controller B before A, then you should - use this option. - - "aic7xxx=extended" - Force the driver to detect extended drive translation - on your controller. This helps those people who have cards without - a SEEPROM make sure that linux and all other operating systems think - the same way about your hard drives. - - "aic7xxx=scbram" - Some cards have external SCB RAM that can be used to - give the card more hardware SCB slots. This allows the driver to use - that SCB RAM. Without this option, the driver won't touch the SCB - RAM because it is known to cause problems on a few cards out there - (such as 3985 class cards). - - "aic7xxx=irq_trigger:x" - Replace x with either 0 or 1 to force the kernel - to use the correct IRQ type for your card. This only applies to EISA - based controllers. On these controllers, 0 is for Edge triggered - interrupts, and 1 is for Level triggered interrupts. If you aren't - sure or don't know which IRQ trigger type your EISA card uses, then - let the kernel autodetect the trigger type. - - "aic7xxx=verbose" - This option can be used in one of two ways. If you - simply specify aic7xxx=verbose, then the kernel will automatically - pick the default set of verbose messages for you to see. - Alternatively, you can specify the command as - "aic7xxx=verbose:0xXXXX" where the X entries are replaced with - hexadecimal digits. This option is a bit field type option. For - a full listing of the available options, search for the - #define VERBOSE_xxxxxx lines in the aic7xxx.c file. If you want - verbose messages, then it is recommended that you simply use the - aic7xxx=verbose variant of this command. - - "aic7xxx=pci_parity:x" - This option controls whether or not the driver - enables PCI parity error checking on the PCI bus. By default, this - checking is disabled. To enable the checks, simply specify pci_parity - with no value afterwords. To reverse the parity from even to odd, - supply any number other than 0 or 255. In short: - pci_parity - Even parity checking (even is the normal PCI parity) - pci_parity:x - Where x > 0, Odd parity checking - pci_parity:0 - No check (default) - NOTE: In order to get Even PCI parity checking, you must use the - version of the option that does not include the : and a number at - the end (unless you want to enter exactly 2^32 - 1 as the number). - - "aic7xxx=no_probe" - This option will disable the probing for any VLB - based 2842 controllers and any EISA based controllers. This is - needed on certain newer motherboards where the normal EISA I/O ranges - have been claimed by other PCI devices. Probing on those machines - will often result in the machine crashing or spontaneously rebooting - during startup. Examples of machines that need this are the - Dell PowerEdge 6300 machines. - - "aic7xxx=seltime:2" - This option controls how long the card waits - during a device selection sequence for the device to respond. - The original SCSI spec says that this "should be" 256ms. This - is generally not required with modern devices. However, some - very old SCSI I devices need the full 256ms. Most modern devices - can run fine with only 64ms. The default for this option is - 64ms. If you need to change this option, then use the following - table to set the proper value in the example above: - 0 - 256ms - 1 - 128ms - 2 - 64ms - 3 - 32ms - - "aic7xxx=panic_on_abort" - This option is for debugging and will cause - the driver to panic the linux kernel and freeze the system the first - time the drivers abort or reset routines are called. This is most - helpful when some problem causes infinite reset loops that scroll too - fast to see. By using this option, you can write down what the errors - actually are and send that information to me so it can be fixed. - - "aic7xxx=dump_card" - This option will print out the *entire* set of - configuration registers on the card during the init sequence. This - is a debugging aid used to see exactly what state the card is in - when we finally finish our initialization routines. If you don't - have documentation on the chipsets, this will do you absolutely - no good unless you are simply trying to write all the information - down in order to send it to me. - - "aic7xxx=dump_sequencer" - This is the same as the above options except - that instead of dumping the register contents on the card, this - option dumps the contents of the sequencer program RAM. This gives - the ability to verify that the instructions downloaded to the - card's sequencer are indeed what they are suppossed to be. Again, - unless you have documentation to tell you how to interpret these - numbers, then it is totally useless. - - "aic7xxx=override_term:0xffffffff" - This option is used to force the - termination on your SCSI controllers to a particular setting. This - is a bit mask variable that applies for up to 8 aic7xxx SCSI channels. - Each channel gets 4 bits, divided as follows: - bit 3 2 1 0 - | | | Enable/Disable Single Ended Low Byte Termination - | | En/Disable Single Ended High Byte Termination - | En/Disable Low Byte LVD Termination - En/Disable High Byte LVD Termination - - The upper 2 bits that deal with LVD termination only apply to Ultra2 - controllers. Futhermore, due to the current Ultra2 controller - designs, these bits are tied together such that setting either bit - enables both low and high byte LVD termination. It is not possible - to only set high or low byte LVD termination in this manner. This is - an artifact of the BIOS definition on Ultra2 controllers. For other - controllers, the only important bits are the two lowest bits. Setting - the higher bits on non-Ultra2 controllers has no effect. A few - examples of how to use this option: - - Enable low and high byte termination on a non-ultra2 controller that - is the first aic7xxx controller (the correct bits are 0011), - aic7xxx=override_term:0x3 - - Enable all termination on the third aic7xxx controller, high byte - termination on the second aic7xxx controller, and low and high byte - SE termination on the first aic7xxx controller - (bits are 1111 0010 0011), - aic7xxx=override_term:0xf23 - - No attempt has been made to make this option non-cryptic. It really - shouldn't be used except in dire circumstances, and if that happens, - I'm probably going to be telling you what to set this to anyway :) - - "aic7xxx=stpwlev:0xffffffff" - This option is used to control the STPWLEV - bit in the DEVCONFIG PCI register. Currently, this is one of the - very few registers that we have absolutely *no* way of detecting - what the variable should be. It depends entirely on how the chipset - and external terminators were coupled by the card/motherboard maker. - Further, a chip reset (at power up) always sets this bit to 0. If - there is no BIOS to run on the chipset/card (such as with a 2910C - or a motherboard controller with the BIOS totally disabled) then - the variable may not get set properly. Of course, if the proper - setting was 0, then that's what it would be after the reset, but if - the proper setting is actually 1.....you get the picture. Now, since - we can't detect this at all, I've added this option to force the - setting. If you have a BIOS on your controller then you should never - need to use this option. However, if you are having lots of SCSI - reset problems and can't seem to get them knocked out, this may help. - - Here's a test to know for certain if you need this option. Make - a boot floppy that you can use to boot your computer up and that - will detect the aic7xxx controller. Next, power down your computer. - While it's down, unplug all SCSI cables from your Adaptec SCSI - controller. Boot the system back up to the Adaptec EZ-SCSI BIOS - and then make sure that termination is enabled on your adapter (if - you have an Adaptec BIOS of course). Next, boot up the floppy you - made and wait for it to detect the aic7xxx controller. If the kernel - finds the controller fine, says scsi : x hosts and then tries to - detect your devices like normal, up to the point where it fails to - mount your root file system and panics, then you're fine. If, on - the other hand, the system goes into an infinite reset loop, then - you need to use this option and/or the previous option to force the - proper termination settings on your controller. If this happens, - then you next need to figure out what your settings should be. - - To find the correct settings, power your machine back down, connect - back up the SCSI cables, and boot back into your machine like normal. - However, boot with the aic7xxx=verbose:0x39 option. Record the - initial DEVCONFIG values for each of your aic7xxx controllers as - they are listed, and also record what the machine is detecting as - the proper termination on your controllers. NOTE: the order in - which the initial DEVCONFIG values are printed out is not gauranteed - to be the same order as the SCSI controllers are registered. The - above option and this option both work on the order of the SCSI - controllers as they are registered, so make sure you match the right - DEVCONFIG values with the right controllers if you have more than - one aic7xxx controller. - - Once you have the detected termination settings and the initial - DEVCONFIG values for each controller, then figure out what the - termination on each of the controllers *should* be. Hopefully, that - part is correct, but it could possibly be wrong if there is - bogus cable detection logic on your controller or something similar. - If all the controllers have the correct termination settings, then - don't set the aic7xxx=override_term variable at all, leave it alone. - Next, on any controllers that go into an infinite reset loop when - you unplug all the SCSI cables, get the starting DEVCONFIG value. - If the initial DEVCONFIG value is divisible by 2, then the correct - setting for that controller is 0. If it's an odd number, then - the correct setting for that controller is 1. For any other - controllers that didn't have an infinite reset problem, then reverse - the above options. If DEVCONFIG was even, then the correct setting - is 1, if not then the correct setting is 0. - - Now that you know what the correct setting was for each controller, - we need to encode that into the aic7xxx=stpwlev:0x... variable. - This variable is a bit field encoded variable. Bit 0 is for the first - aic7xxx controller, bit 1 for the next, etc. Put all these bits - together and you get a number. For example, if the third aic7xxx - needed a 1, but the second and first both needed a 0, then the bits - would be 100 in binary. This then translates to 0x04. You would - therefore set aic7xxx=stpwlev:0x04. This is fairly standard binary - to hexadecimal conversions here. If you aren't up to speed on the - binary->hex conversion then send an email to the aic7xxx mailing - list and someone can help you out. - - "aic7xxx=tag_info:{{8,8..},{8,8..},..}" - This option is used to disable - or enable Tagged Command Queueing (TCQ) on specific devices. As of - driver version 5.1.11, TCQ is now either on or off by default - according to the setting you choose during the make config process. - In order to en/disable TCQ for certian devices at boot time, a user - may use this boot param. The driver will then parse this message out - and en/disable the specific device entries that are present based upon - the value given. The param line is parsed in the following manner: - - { - first instance indicates the start of this parameter values - second instance is the start of entries for a particular - device entry - } - end the entries for a particular host adapter, or end the entire - set of parameter entries - , - move to next entry. Inside of a set of device entries, this - moves us to the next device on the list. Outside of device - entries, this moves us to the next host adapter - . - Same effect as , but is safe to use with insmod. - x - the number to enter into the array at this position. - 0 = Enable tagged queueing on this device and use the default - queue depth - 1-254 = Enable tagged queueing on this device and use this - number as the queue depth - 255 = Disable tagged queueing on this device. - Note: anything above 32 for an actual queue depth is wasteful - and not recommended. - - A few examples of how this can be used: - - tag_info:{{8,12,,0,,255,4}} - This line will only effect the first aic7xxx card registered. It - will set scsi id 0 to a queue depth of 8, id 1 to 12, leave id 2 - at the default, set id 3 to tagged queueing enabled and use the - default queue depth, id 4 default, id 5 disabled, and id 6 to 4. - Any not specified entries stay at the default value, repeated - commas with no value specified will simply increment to the next id - without changing anything for the missing values. - - tag_info:{,,,{,,,255}} - First, second, and third adapters at default values. Fourth - adapter, id 3 is disabled. Notice that leading commas simply - increment what the first number effects, and there are no need - for trailing commas. When you close out an adapter, or the - entire entry, anything not explicitly set stays at the default - value. - - A final note on this option. The scanner I used for this isn't - perfect or highly robust. If you mess the line up, the worst that - should happen is that the line will get ignored. If you don't - close out the entire entry with the final bracket, then any other - aic7xxx options after this will get ignored. So, in general, be - sure of what you are entering, and after you have it right, just - add it to the lilo.conf file so there won't be any mistakes. As - a means of checking this parser, the entire tag_info array for - each card is now printed out in the /proc/scsi/aic7xxx/x file. You - can use that to verify that your options were parsed correctly. - - Boot command line options may be combined to form the proper set of options - a user might need. For example, the following is valid: - - aic7xxx=verbose,extended,irq_trigger:1 - - The only requirement is that individual options be separated by a comma or - a period on the command line. - - Module Loading command options - ------------------------------ - When loading the aic7xxx driver as a module, the exact same options are - available to the user. However, the syntax to specify the options changes - slightly. For insmod, you need to wrap the aic7xxx= argument in quotes - and replace all ',' with '.'. So, for example, a valid insmod line - would be: - - insmod aic7xxx aic7xxx='verbose.irq_trigger:1.extended' - - This line should result in the *exact* same behaviour as if you typed - it in at the lilo prompt and the driver was compiled into the kernel - instead of being a module. The reason for the single quote is so that - the shell won't try to interpret anything in the line, such as {. - Insmod assumes any options starting with a letter instead of a number - is a character string (which is what we want) and by switching all of - the commas to periods, insmod won't interpret this as more than one - string and write junk into our binary image. I consider it a bug in - the insmod program that even if you wrap your string in quotes (quotes - that pass the shell mind you and that insmod sees) it still treates - a comma inside of those quotes as starting a new variable, resulting - in memory scribbles if you don't switch the commas to periods. - - - Kernel Compile options - ------------------------------ - The various kernel compile time options for this driver are now fairly - well documented in the file Documentation/Configure.help. In order to - see this documentation, you need to use one of the advanced configuration - programs (menuconfig and xconfig). If you are using the "make menuconfig" - method of configuring your kernel, then you would simply highlight the - option in question and hit the ? key. If you are using the "make xconfig" - method of configuring your kernel, then simply click on the help button - next to the option you have questions about. The help information from - the Configure.help file will then get automatically displayed. - - /proc support - ------------------------------ - The /proc support for the AIC7xxx can be found in the /proc/scsi/aic7xxx/ - directory. That directory contains a file for each SCSI controller in - the system. Each file presents the current configuration and transfer - statistics (enabled with #define in aic7xxx.c) for each controller. - - Thanks to Michael Neuffer for his upper-level SCSI help, and - Matthew Jacob for statistics support. - - Debugging the driver - ------------------------------ - Should you have problems with this driver, and would like some help in - getting them solved, there are a couple debugging items built into - the driver to facilitate getting the needed information from the system. - In general, I need a complete description of the problem, with as many - logs as possible concerning what happens. To help with this, there is - a command option aic7xxx=panic_on_abort. This option, when set, forces - the driver to panic the kernel on the first SCSI abort issued by the - mid level SCSI code. If your system is going to reset loops and you - can't read the screen, then this is what you need. Not only will it - stop the system, but it also prints out a large amount of state - information in the process. Second, if you specify the option - "aic7xxx=verbose:0x1ffff", the system will print out *SOOOO* much - information as it runs that you won't be able to see anything. - However, this can actually be very useful if your machine simply - locks up when trying to boot, since it will pin-point what was last - happening (in regards to the aic7xxx driver) immediately prior to - the lockup. This is really only useful if your machine simply can - not boot up successfully. If you can get your machine to run, then - this will produce far too much information. - - FTP sites - ------------------------------ - ftp://ftp.redhat.com/pub/aic/ - - Out of date. I used to keep stuff here, but too many people - complained about having a hard time getting into Red Hat's ftp - server. So use the web site below instead. - ftp://ftp.pcnet.com/users/eischen/Linux/ - - Dan Eischen's driver distribution area - ftp://ekf2.vsb.cz/pub/linux/kernel/aic7xxx/ftp.teleport.com/ - - European Linux mirror of Teleport site - - Web sites - ------------------------------ - http://people.redhat.com/dledford/ - - My web site, also the primary aic7xxx site with several related - pages. - -Dean W. Gehnert -deang@teleport.com - -$Revision: 3.0 $ - -Modified by Doug Ledford 1998-2000 - +==================================================================== += Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.10 = += README for = += The Linux Operating System = +==================================================================== + +The following information is available in this file: + + 1. Supported Hardware + 2. Command Line Options + 3. Contacting Adaptec + +1. Supported Hardware + + The following Adaptec SCSI Chips and Host Adapters are supported by + the aic7xxx driver. + + Chip MIPS Host Bus MaxSync MaxWidth SCBs Notes + --------------------------------------------------------------- + aic7770 10 EISA/VL 10MHz 16Bit 4 1 + aic7850 10 PCI/32 10MHz 8Bit 3 + aic7855 10 PCI/32 10MHz 8Bit 3 + aic7856 10 PCI/32 10MHz 8Bit 3 + aic7859 10 PCI/32 20MHz 8Bit 3 + aic7860 10 PCI/32 20MHz 8Bit 3 + aic7870 10 PCI/32 10MHz 16Bit 16 + aic7880 10 PCI/32 20MHz 16Bit 16 + aic7890 20 PCI/32 40MHz 16Bit 16 3 4 5 6 7 8 + aic7891 20 PCI/64 40MHz 16Bit 16 3 4 5 6 7 8 + aic7892 20 PCI/64-66 80MHz 16Bit 16 3 4 5 6 7 8 + aic7895 15 PCI/32 20MHz 16Bit 16 2 3 4 5 + aic7895C 15 PCI/32 20MHz 16Bit 16 2 3 4 5 8 + aic7896 20 PCI/32 40MHz 16Bit 16 2 3 4 5 6 7 8 + aic7897 20 PCI/64 40MHz 16Bit 16 2 3 4 5 6 7 8 + aic7899 20 PCI/64-66 80MHz 16Bit 16 2 3 4 5 6 7 8 + + 1. Multiplexed Twin Channel Device - One controller servicing two + busses. + 2. Multi-function Twin Channel Device - Two controllers on one chip. + 3. Command Channel Secondary DMA Engine - Allows scatter gather list + and SCB prefetch. + 4. 64 Byte SCB Support - Allows disconnected, unttagged request table + for all possible target/lun combinations. + 5. Block Move Instruction Support - Doubles the speed of certain + sequencer operations. + 6. `Bayonet' style Scatter Gather Engine - Improves S/G prefetch + performance. + 7. Queuing Registers - Allows queuing of new transactions without + pausing the sequencer. + 8. Multiple Target IDs - Allows the controller to respond to selection + as a target on multiple SCSI IDs. + + Controller Chip Host-Bus Int-Connectors Ext-Connectors Notes + -------------------------------------------------------------------------- + AHA-274X[A] aic7770 EISA SE-50M SE-HD50F + AHA-274X[A]W aic7770 EISA SE-HD68F SE-HD68F + SE-50M + AHA-274X[A]T aic7770 EISA 2 X SE-50M SE-HD50F + AHA-2842 aic7770 VL SE-50M SE-HD50F + AHA-2940AU aic7860 PCI/32 SE-50M SE-HD50F + AVA-2902I aic7860 PCI/32 SE-50M + AVA-2902E aic7860 PCI/32 SE-50M + AVA-2906 aic7856 PCI/32 SE-50M SE-DB25F + APC-7850 aic7850 PCI/32 SE-50M 1 + AVA-2940 aic7860 PCI/32 SE-50M + AHA-2920B aic7860 PCI/32 SE-50M + AHA-2930B aic7860 PCI/32 SE-50M + AHA-2920C aic7856 PCI/32 SE-50M SE-HD50F + AHA-2930C aic7860 PCI/32 SE-50M + AHA-2930C aic7860 PCI/32 SE-50M + AHA-2910C aic7860 PCI/32 SE-50M + AHA-2915C aic7860 PCI/32 SE-50M + AHA-2940AU/CN aic7860 PCI/32 SE-50M SE-HD50F + AHA-2944W aic7870 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M + AHA-3940W aic7870 PCI/32 2 X SE-HD68F SE-HD68F 2 + AHA-2940UW aic7880 PCI/32 SE-HD68F + SE-50M SE-HD68F + AHA-2940U aic7880 PCI/32 SE-50M SE-HD50F + AHA-2940D aic7880 PCI/32 + AHA-2940 A/T aic7880 PCI/32 + AHA-2940D A/T aic7880 PCI/32 + AHA-3940UW aic7880 PCI/32 2 X SE-HD68F SE-HD68F 3 + AHA-3940UWD aic7880 PCI/32 2 X SE-HD68F 2 X SE-VHD68F 3 + AHA-3940U aic7880 PCI/32 2 X SE-50M SE-HD50F 3 + AHA-2944UW aic7880 PCI/32 HVD-HD68F HVD-HD68F + HVD-50M + AHA-3944UWD aic7880 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F 3 + AHA-4944UW aic7880 PCI/32 + AHA-2930UW aic7880 PCI/32 + AHA-2940UW Pro aic7880 PCI/32 SE-HD68F SE-HD68F 4 + SE-50M + AHA-2940UW/CN aic7880 PCI/32 + AHA-2940UDual aic7895 PCI/32 + AHA-2940UWDual aic7895 PCI/32 + AHA-3940UWD aic7895 PCI/32 + AHA-3940AUW aic7895 PCI/32 + AHA-3940AUWD aic7895 PCI/32 + AHA-3940AU aic7895 PCI/32 + AHA-3944AUWD aic7895 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F + AHA-2940U2B aic7890 PCI/32 LVD-HD68F LVD-HD68F + AHA-2940U2 OEM aic7891 PCI/64 + AHA-2940U2W aic7890 PCI/32 LVD-HD68F LVD-HD68F + SE-HD68F + SE-50M + AHA-2950U2B aic7891 PCI/64 LVD-HD68F LVD-HD68F + AHA-2930U2 aic7890 PCI/32 LVD-HD68F SE-HD50F + SE-50M + AHA-3950U2B aic7897 PCI/64 + AHA-3950U2D aic7897 PCI/64 + AHA-29160 aic7892 PCI/64-66 + AHA-29160 CPQ aic7892 PCI/64-66 + AHA-29160N aic7892 PCI/32 LVD-HD68F SE-HD50F + SE-50M + AHA-29160LP aic7892 PCI/64-66 + AHA-19160 aic7892 PCI/64-66 + AHA-29150LP aic7892 PCI/64-66 + AHA-29130LP aic7892 PCI/64-66 + AHA-3960D aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + AHA-3960D CPQ aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + AHA-39160 aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F + LVD-50M + + 1. No BIOS support + 2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus + 3. DEC2115X PCI-PCI bridge with multiple controller chips on secondary bus + 4. All three SCSI connectors may be used simultaneously without + SCSI "stub" effects. + +2. Command Line Options + + WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS + INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. + USE THEM WITH CAUTION. + + Edit the file "modules.conf" in the directory /etc and add/edit a + line containing 'options aic7xxx=[command[,command...]]' where + 'command' is one or more of the following: + ----------------------------------------------------------------- + Option: verbose + Definition: enable additional informative messages during + driver operation. + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: debug:[value] + Definition: Enables various levels of debugging information + Possible Values: 0x0000 = no debugging, 0xffff = full debugging + Default Value: 0x0000 + ----------------------------------------------------------------- + Option: no_reset + Definition: Do not reset the bus during the initial probe + phase + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: extended + Definition: Force extended translation on the controller + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: periodic_otag + Definition: Send an ordered tag periodically to prevent + tag starvation. Needed for some older devices + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: reverse_scan + Definition: Probe the scsi bus in reverse order, starting + with target 15 + Possible Values: This option is a flag + Default Value: disabled + ----------------------------------------------------------------- + Option: global_tag_depth + Definition: Global tag depth for all targets on all busses. + This option sets the default tag depth which + may be selectively overridden vi the tag_info + option. + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} + Definition: Set the per-target tagged queue depth on a + per controller basis. Both controllers and targets + may be ommitted indicating that they should retain + the default tag depth. + Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} + On Controller 0 + specifies a tag depth of 16 for target 0 + specifies a tag depth of 64 for target 3 + specifies a tag depth of 8 for targets 4 and 5 + leaves target 6 at the default + specifies a tag depth of 32 for targets 1,2,7-15 + All other targets retain the default depth. + + tag_info:{{},{32,,32}} + On Controller 1 + specifies a tag depth of 32 for targets 0 and 2 + All other targets retain the default depth. + + Possible Values: 1 - 253 + Default Value: 32 + ----------------------------------------------------------------- + Option: seltime:[value] + Definition: Specifies the selection timeout value + Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms + Default Value: 0 + ----------------------------------------------------------------- + + Example: 'options aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" + enables verbose logging, Disable EISA/VLB probing, + and set tag depth on Controller 1/Target 2 to 10 tags. + +3. Contacting Adaptec + + A Technical Support Identification (TSID) Number is required for + Adaptec technical support. + - The 12-digit TSID can be found on the white barcode-type label + included inside the box with your product. The TSID helps us + provide more efficient service by accurately identifying your + product and support status. + Support Options + - Search the Adaptec Support Knowledgebase (ASK) at + http://ask.adaptec.com for articles, troubleshooting tips, and + frequently asked questions for your product. + - For support via Email, submit your question to Adaptec's + Technical Support Specialists at http://ask.adaptec.com. + + North America + - Visit our Web site at http://www.adaptec.com. + - To speak with a Fibre Channel/RAID/External Storage Technical + Support Specialist, call 1-321-207-2000, + Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For Technical Support in all other technologies including + SCSI, call 1-408-934-7274, + Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. + (Not open on holidays) + - For after hours support, call 1-800-416-8066 ($99/call, + $149/call on holidays) + - To order Adaptec products including software and cables, call + 1-800-442-7274 or 1-408-957-7274. You can also visit our + online store at http://www.adaptecstore.com + + Europe + - Visit our Web site at http://www.adaptec-europe.com. + - English and French: To speak with a Technical Support + Specialist, call one of the following numbers: + - English: +32-2-352-3470 + - French: +32-2-352-3460 + Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET + Friday, 10:00 to 12:30, 13:30 to 16:30 CET + - German: To speak with a Technical Support Specialist, + call +49-89-456-40660 + Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET + Friday, 09:30 to 12:30, 13:30 to 15:00 CET + - To order Adaptec products, including accessories and cables: + - UK: +0800-96-65-26 or fax +0800-731-02-95 + - Other European countries: +32-11-300-379 + + Australia and New Zealand + - Visit our Web site at http://www.adaptec.com.au. + - To speak with a Technical Support Specialist, call + +612-9416-0698 + Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT + (Not open on holidays) + + Japan + - To speak with a Technical Support Specialist, call + +81-3-5308-6120 + Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to + 6:00 p.m. TSC + + Hong Kong and China + - To speak with a Technical Support Specialist, call + +852-2869-7200 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100. + + Singapore + - To speak with a Technical Support Specialist, call + +65-245-7470 + Hours: Monday-Friday, 10:00 to 17:00. + - Fax Technical Support at +852-2869-7100 + +------------------------------------------------------------------- + +(c) 2002 Adaptec, Inc. All Rights Reserved. No part of this +publication may be reproduced, stored in a retrieval system, or +transmitted in any form or by any means, electronic, mechanical, +photocopying, recording or otherwise, without prior written consent +of Adaptec, Inc., 691 South Milpitas Blvd., Milpitas, CA 95035. diff --git a/drivers/scsi/aic7xxx/Kconfig.aic79xx b/drivers/scsi/aic7xxx/Kconfig.aic79xx new file mode 100644 index 000000000000..d9fc9a9c8156 --- /dev/null +++ b/drivers/scsi/aic7xxx/Kconfig.aic79xx @@ -0,0 +1,95 @@ +# +# AIC79XX 2.5.X Kernel configuration File. +# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic79xx#1 $ +# +config SCSI_AIC79XX + tristate "Adaptec AIC79xx U320 support" + help + This driver supports all of Adaptec's Ultra 320 PCI-X + based SCSI controllers. + +config AIC79XX_CMDS_PER_DEVICE + int "Maximum number of TCQ commands per device" + depends on SCSI_AIC79XX + default "32" + ---help--- + Specify the number of commands you would like to allocate per SCSI + device when Tagged Command Queueing (TCQ) is enabled on that device. + + This is an upper bound value for the number of tagged transactions + to be used for any device. The aic7xxx driver will automatically + vary this number based on device behavior. For devices with a + fixed maximum, the driver will eventually lock to this maximum + and display a console message inidicating this value. + + Due to resource allocation issues in the Linux SCSI mid-layer, using + a high number of commands per device may result in memory allocation + failures when many devices are attached to the system. For this reason, + the default is set to 32. Higher values may result in higer performance + on some devices. The upper bound is 253. 0 disables tagged queueing. + + Per device tag depth can be controlled via the kernel command line + "tag_info" option. See drivers/scsi/aic7xxx/README.aic79xx + for details. + +config AIC79XX_RESET_DELAY_MS + int "Initial bus reset delay in milli-seconds" + depends on SCSI_AIC79XX + default "15000" + ---help--- + The number of milliseconds to delay after an initial bus reset. + The bus settle delay following all error recovery actions is + dictated by the SCSI layer and is not affected by this value. + + Default: 15000 (15 seconds) + +config AIC79XX_BUILD_FIRMWARE + bool "Build Adapter Firmware with Kernel Build" + depends on SCSI_AIC79XX + help + This option should only be enabled if you are modifying the firmware + source to the aic79xx driver and wish to have the generated firmware + include files updated during a normal kernel build. The assembler + for the firmware requires lex and yacc or their equivalents, as well + as the db v1 library. You may have to install additional packages + or modify the assembler Makefile or the files it includes if your + build environment is different than that of the author. + +config AIC79XX_ENABLE_RD_STRM + bool "Enable Read Streaming for All Targets" + depends on SCSI_AIC79XX + help + Read Streaming is a U320 protocol option that should enhance + performance. Early U320 drive firmware actually performs slower + with read streaming enabled so it is disabled by default. Read + Streaming can be configured in much the same way as tagged queueing + using the "rd_strm" command line option. See + drivers/scsi/aic7xxx/README.aic79xx for details. + +config AIC79XX_DEBUG_ENABLE + bool "Compile in Debugging Code" + depends on SCSI_AIC79XX + default y + help + Compile in aic79xx debugging code that can be useful in diagnosing + driver errors. + +config AIC79XX_DEBUG_MASK + int "Debug code enable mask (16383 for all debugging)" + depends on SCSI_AIC79XX + default "0" + help + Bit mask of debug options that is only valid if the + CONFIG_AIC79XX_DEBUG_ENBLE option is enabled. The bits in this mask + are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the + variable ahd_debug in that file to find them. + +config AIC79XX_REG_PRETTY_PRINT + bool "Decode registers during diagnostics" + depends on SCSI_AIC79XX + default y + help + Compile in register value tables for the output of expanded register + contents in diagnostics. This make it much easier to understand debug + output without having to refer to a data book and/or the aic7xxx.reg + file. diff --git a/drivers/scsi/aic7xxx/Kconfig b/drivers/scsi/aic7xxx/Kconfig.aic7xxx index 8b57621e4cf0..e36902d0df62 100644 --- a/drivers/scsi/aic7xxx/Kconfig +++ b/drivers/scsi/aic7xxx/Kconfig.aic7xxx @@ -1,6 +1,6 @@ # # AIC7XXX and AIC79XX 2.5.X Kernel configuration File. -# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig#2 $ +# $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Kconfig.aic7xxx#2 $ # config SCSI_AIC7XXX tristate "Adaptec AIC7xxx Fast -> U160 support" @@ -104,89 +104,3 @@ config SCSI_AIC79XX help This driver supports all of Adaptec's Ultra 320 PCI-X based SCSI controllers. - -config AIC79XX_CMDS_PER_DEVICE - int "Maximum number of TCQ commands per device" - depends on SCSI_AIC79XX - default "32" - ---help--- - Specify the number of commands you would like to allocate per SCSI - device when Tagged Command Queueing (TCQ) is enabled on that device. - - This is an upper bound value for the number of tagged transactions - to be used for any device. The aic7xxx driver will automatically - vary this number based on device behavior. For devices with a - fixed maximum, the driver will eventually lock to this maximum - and display a console message inidicating this value. - - Due to resource allocation issues in the Linux SCSI mid-layer, using - a high number of commands per device may result in memory allocation - failures when many devices are attached to the system. For this reason, - the default is set to 32. Higher values may result in higer performance - on some devices. The upper bound is 253. 0 disables tagged queueing. - - Per device tag depth can be controlled via the kernel command line - "tag_info" option. See drivers/scsi/aic7xxx/README.aic79xx - for details. - -config AIC79XX_RESET_DELAY_MS - int "Initial bus reset delay in milli-seconds" - depends on SCSI_AIC79XX - default "15000" - ---help--- - The number of milliseconds to delay after an initial bus reset. - The bus settle delay following all error recovery actions is - dictated by the SCSI layer and is not affected by this value. - - Default: 15000 (15 seconds) - -config AIC79XX_BUILD_FIRMWARE - bool "Build Adapter Firmware with Kernel Build" - depends on SCSI_AIC79XX - help - This option should only be enabled if you are modifying the firmware - source to the aic79xx driver and wish to have the generated firmware - include files updated during a normal kernel build. The assembler - for the firmware requires lex and yacc or their equivalents, as well - as the db v1 library. You may have to install additional packages - or modify the assembler Makefile or the files it includes if your - build environment is different than that of the author. - -config AIC79XX_ENABLE_RD_STRM - bool "Enable Read Streaming for All Targets" - depends on SCSI_AIC79XX - help - Read Streaming is a U320 protocol option that should enhance - performance. Early U320 drive firmware actually performs slower - with read streaming enabled so it is disabled by default. Read - Streaming can be configured in much the same way as tagged queueing - using the "rd_strm" command line option. See - drivers/scsi/aic7xxx/README.aic79xx for details. - -config AIC79XX_DEBUG_ENABLE - bool "Compile in Debugging Code" - depends on SCSI_AIC79XX - default y - help - Compile in aic79xx debugging code that can be useful in diagnosing - driver errors. - -config AIC79XX_DEBUG_MASK - int "Debug code enable mask (16383 for all debugging)" - depends on SCSI_AIC79XX - default "0" - help - Bit mask of debug options that is only valid if the - CONFIG_AIC79XX_DEBUG_ENBLE option is enabled. The bits in this mask - are defined in the drivers/scsi/aic7xxx/aic79xx.h - search for the - variable ahd_debug in that file to find them. - -config AIC79XX_REG_PRETTY_PRINT - bool "Decode registers during diagnostics" - depends on SCSI_AIC79XX - default y - help - Compile in register value tables for the output of expanded register - contents in diagnostics. This make it much easier to understand debug - output without having to refer to a data book and/or the aic7xxx.reg - file. diff --git a/drivers/scsi/aic7xxx/README.aic7xxx b/drivers/scsi/aic7xxx/README.aic7xxx deleted file mode 100644 index 2246ca8978eb..000000000000 --- a/drivers/scsi/aic7xxx/README.aic7xxx +++ /dev/null @@ -1,294 +0,0 @@ -==================================================================== -= Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v6.2.10 = -= README for = -= The Linux Operating System = -==================================================================== - -The following information is available in this file: - - 1. Supported Hardware - 2. Command Line Options - 3. Contacting Adaptec - -1. Supported Hardware - - The following Adaptec SCSI Chips and Host Adapters are supported by - the aic7xxx driver. - - Chip MIPS Host Bus MaxSync MaxWidth SCBs Notes - --------------------------------------------------------------- - aic7770 10 EISA/VL 10MHz 16Bit 4 1 - aic7850 10 PCI/32 10MHz 8Bit 3 - aic7855 10 PCI/32 10MHz 8Bit 3 - aic7856 10 PCI/32 10MHz 8Bit 3 - aic7859 10 PCI/32 20MHz 8Bit 3 - aic7860 10 PCI/32 20MHz 8Bit 3 - aic7870 10 PCI/32 10MHz 16Bit 16 - aic7880 10 PCI/32 20MHz 16Bit 16 - aic7890 20 PCI/32 40MHz 16Bit 16 3 4 5 6 7 8 - aic7891 20 PCI/64 40MHz 16Bit 16 3 4 5 6 7 8 - aic7892 20 PCI/64-66 80MHz 16Bit 16 3 4 5 6 7 8 - aic7895 15 PCI/32 20MHz 16Bit 16 2 3 4 5 - aic7895C 15 PCI/32 20MHz 16Bit 16 2 3 4 5 8 - aic7896 20 PCI/32 40MHz 16Bit 16 2 3 4 5 6 7 8 - aic7897 20 PCI/64 40MHz 16Bit 16 2 3 4 5 6 7 8 - aic7899 20 PCI/64-66 80MHz 16Bit 16 2 3 4 5 6 7 8 - - 1. Multiplexed Twin Channel Device - One controller servicing two - busses. - 2. Multi-function Twin Channel Device - Two controllers on one chip. - 3. Command Channel Secondary DMA Engine - Allows scatter gather list - and SCB prefetch. - 4. 64 Byte SCB Support - Allows disconnected, unttagged request table - for all possible target/lun combinations. - 5. Block Move Instruction Support - Doubles the speed of certain - sequencer operations. - 6. `Bayonet' style Scatter Gather Engine - Improves S/G prefetch - performance. - 7. Queuing Registers - Allows queuing of new transactions without - pausing the sequencer. - 8. Multiple Target IDs - Allows the controller to respond to selection - as a target on multiple SCSI IDs. - - Controller Chip Host-Bus Int-Connectors Ext-Connectors Notes - -------------------------------------------------------------------------- - AHA-274X[A] aic7770 EISA SE-50M SE-HD50F - AHA-274X[A]W aic7770 EISA SE-HD68F SE-HD68F - SE-50M - AHA-274X[A]T aic7770 EISA 2 X SE-50M SE-HD50F - AHA-2842 aic7770 VL SE-50M SE-HD50F - AHA-2940AU aic7860 PCI/32 SE-50M SE-HD50F - AVA-2902I aic7860 PCI/32 SE-50M - AVA-2902E aic7860 PCI/32 SE-50M - AVA-2906 aic7856 PCI/32 SE-50M SE-DB25F - APC-7850 aic7850 PCI/32 SE-50M 1 - AVA-2940 aic7860 PCI/32 SE-50M - AHA-2920B aic7860 PCI/32 SE-50M - AHA-2930B aic7860 PCI/32 SE-50M - AHA-2920C aic7856 PCI/32 SE-50M SE-HD50F - AHA-2930C aic7860 PCI/32 SE-50M - AHA-2930C aic7860 PCI/32 SE-50M - AHA-2910C aic7860 PCI/32 SE-50M - AHA-2915C aic7860 PCI/32 SE-50M - AHA-2940AU/CN aic7860 PCI/32 SE-50M SE-HD50F - AHA-2944W aic7870 PCI/32 HVD-HD68F HVD-HD68F - HVD-50M - AHA-3940W aic7870 PCI/32 2 X SE-HD68F SE-HD68F 2 - AHA-2940UW aic7880 PCI/32 SE-HD68F - SE-50M SE-HD68F - AHA-2940U aic7880 PCI/32 SE-50M SE-HD50F - AHA-2940D aic7880 PCI/32 - AHA-2940 A/T aic7880 PCI/32 - AHA-2940D A/T aic7880 PCI/32 - AHA-3940UW aic7880 PCI/32 2 X SE-HD68F SE-HD68F 3 - AHA-3940UWD aic7880 PCI/32 2 X SE-HD68F 2 X SE-VHD68F 3 - AHA-3940U aic7880 PCI/32 2 X SE-50M SE-HD50F 3 - AHA-2944UW aic7880 PCI/32 HVD-HD68F HVD-HD68F - HVD-50M - AHA-3944UWD aic7880 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F 3 - AHA-4944UW aic7880 PCI/32 - AHA-2930UW aic7880 PCI/32 - AHA-2940UW Pro aic7880 PCI/32 SE-HD68F SE-HD68F 4 - SE-50M - AHA-2940UW/CN aic7880 PCI/32 - AHA-2940UDual aic7895 PCI/32 - AHA-2940UWDual aic7895 PCI/32 - AHA-3940UWD aic7895 PCI/32 - AHA-3940AUW aic7895 PCI/32 - AHA-3940AUWD aic7895 PCI/32 - AHA-3940AU aic7895 PCI/32 - AHA-3944AUWD aic7895 PCI/32 2 X HVD-HD68F 2 X HVD-VHD68F - AHA-2940U2B aic7890 PCI/32 LVD-HD68F LVD-HD68F - AHA-2940U2 OEM aic7891 PCI/64 - AHA-2940U2W aic7890 PCI/32 LVD-HD68F LVD-HD68F - SE-HD68F - SE-50M - AHA-2950U2B aic7891 PCI/64 LVD-HD68F LVD-HD68F - AHA-2930U2 aic7890 PCI/32 LVD-HD68F SE-HD50F - SE-50M - AHA-3950U2B aic7897 PCI/64 - AHA-3950U2D aic7897 PCI/64 - AHA-29160 aic7892 PCI/64-66 - AHA-29160 CPQ aic7892 PCI/64-66 - AHA-29160N aic7892 PCI/32 LVD-HD68F SE-HD50F - SE-50M - AHA-29160LP aic7892 PCI/64-66 - AHA-19160 aic7892 PCI/64-66 - AHA-29150LP aic7892 PCI/64-66 - AHA-29130LP aic7892 PCI/64-66 - AHA-3960D aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M - AHA-3960D CPQ aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M - AHA-39160 aic7899 PCI/64-66 2 X LVD-HD68F 2 X LVD-VHD68F - LVD-50M - - 1. No BIOS support - 2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus - 3. DEC2115X PCI-PCI bridge with multiple controller chips on secondary bus - 4. All three SCSI connectors may be used simultaneously without - SCSI "stub" effects. - -2. Command Line Options - - WARNING: ALTERING OR ADDING THESE DRIVER PARAMETERS - INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE. - USE THEM WITH CAUTION. - - Edit the file "modules.conf" in the directory /etc and add/edit a - line containing 'options aic7xxx=[command[,command...]]' where - 'command' is one or more of the following: - ----------------------------------------------------------------- - Option: verbose - Definition: enable additional informative messages during - driver operation. - Possible Values: This option is a flag - Default Value: disabled - ----------------------------------------------------------------- - Option: debug:[value] - Definition: Enables various levels of debugging information - Possible Values: 0x0000 = no debugging, 0xffff = full debugging - Default Value: 0x0000 - ----------------------------------------------------------------- - Option: no_reset - Definition: Do not reset the bus during the initial probe - phase - Possible Values: This option is a flag - Default Value: disabled - ----------------------------------------------------------------- - Option: extended - Definition: Force extended translation on the controller - Possible Values: This option is a flag - Default Value: disabled - ----------------------------------------------------------------- - Option: periodic_otag - Definition: Send an ordered tag periodically to prevent - tag starvation. Needed for some older devices - Possible Values: This option is a flag - Default Value: disabled - ----------------------------------------------------------------- - Option: reverse_scan - Definition: Probe the scsi bus in reverse order, starting - with target 15 - Possible Values: This option is a flag - Default Value: disabled - ----------------------------------------------------------------- - Option: global_tag_depth - Definition: Global tag depth for all targets on all busses. - This option sets the default tag depth which - may be selectively overridden vi the tag_info - option. - Possible Values: 1 - 253 - Default Value: 32 - ----------------------------------------------------------------- - Option: tag_info:{{value[,value...]}[,{value[,value...]}...]} - Definition: Set the per-target tagged queue depth on a - per controller basis. Both controllers and targets - may be ommitted indicating that they should retain - the default tag depth. - Examples: tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32} - On Controller 0 - specifies a tag depth of 16 for target 0 - specifies a tag depth of 64 for target 3 - specifies a tag depth of 8 for targets 4 and 5 - leaves target 6 at the default - specifies a tag depth of 32 for targets 1,2,7-15 - All other targets retain the default depth. - - tag_info:{{},{32,,32}} - On Controller 1 - specifies a tag depth of 32 for targets 0 and 2 - All other targets retain the default depth. - - Possible Values: 1 - 253 - Default Value: 32 - ----------------------------------------------------------------- - Option: seltime:[value] - Definition: Specifies the selection timeout value - Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms - Default Value: 0 - ----------------------------------------------------------------- - - Example: 'options aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1" - enables verbose logging, Disable EISA/VLB probing, - and set tag depth on Controller 1/Target 2 to 10 tags. - -3. Contacting Adaptec - - A Technical Support Identification (TSID) Number is required for - Adaptec technical support. - - The 12-digit TSID can be found on the white barcode-type label - included inside the box with your product. The TSID helps us - provide more efficient service by accurately identifying your - product and support status. - Support Options - - Search the Adaptec Support Knowledgebase (ASK) at - http://ask.adaptec.com for articles, troubleshooting tips, and - frequently asked questions for your product. - - For support via Email, submit your question to Adaptec's - Technical Support Specialists at http://ask.adaptec.com. - - North America - - Visit our Web site at http://www.adaptec.com. - - To speak with a Fibre Channel/RAID/External Storage Technical - Support Specialist, call 1-321-207-2000, - Hours: Monday-Friday, 3:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For Technical Support in all other technologies including - SCSI, call 1-408-934-7274, - Hours: Monday-Friday, 6:00 A.M. to 5:00 P.M., PST. - (Not open on holidays) - - For after hours support, call 1-800-416-8066 ($99/call, - $149/call on holidays) - - To order Adaptec products including software and cables, call - 1-800-442-7274 or 1-408-957-7274. You can also visit our - online store at http://www.adaptecstore.com - - Europe - - Visit our Web site at http://www.adaptec-europe.com. - - English and French: To speak with a Technical Support - Specialist, call one of the following numbers: - - English: +32-2-352-3470 - - French: +32-2-352-3460 - Hours: Monday-Thursday, 10:00 to 12:30, 13:30 to 17:30 CET - Friday, 10:00 to 12:30, 13:30 to 16:30 CET - - German: To speak with a Technical Support Specialist, - call +49-89-456-40660 - Hours: Monday-Thursday, 09:30 to 12:30, 13:30 to 16:30 CET - Friday, 09:30 to 12:30, 13:30 to 15:00 CET - - To order Adaptec products, including accessories and cables: - - UK: +0800-96-65-26 or fax +0800-731-02-95 - - Other European countries: +32-11-300-379 - - Australia and New Zealand - - Visit our Web site at http://www.adaptec.com.au. - - To speak with a Technical Support Specialist, call - +612-9416-0698 - Hours: Monday-Friday, 10:00 A.M. to 4:30 P.M., EAT - (Not open on holidays) - - Japan - - To speak with a Technical Support Specialist, call - +81-3-5308-6120 - Hours: Monday-Friday, 9:00 a.m. to 12:00 p.m., 1:00 p.m. to - 6:00 p.m. TSC - - Hong Kong and China - - To speak with a Technical Support Specialist, call - +852-2869-7200 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100. - - Singapore - - To speak with a Technical Support Specialist, call - +65-245-7470 - Hours: Monday-Friday, 10:00 to 17:00. - - Fax Technical Support at +852-2869-7100 - -------------------------------------------------------------------- - -(c) 2002 Adaptec, Inc. All Rights Reserved. No part of this -publication may be reproduced, stored in a retrieval system, or -transmitted in any form or by any means, electronic, mechanical, -photocopying, recording or otherwise, without prior written consent -of Adaptec, Inc., 691 South Milpitas Blvd., Milpitas, CA 95035. diff --git a/drivers/scsi/aic7xxx/aic79xx_host.h b/drivers/scsi/aic7xxx/aic79xx_host.h deleted file mode 100644 index da918de0c4d5..000000000000 --- a/drivers/scsi/aic7xxx/aic79xx_host.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Adaptec AIC79xx device driver host template for Linux. - * - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_host.h#11 $ - */ - -#ifndef _AIC79XX_LINUX_HOST_H_ -#define _AIC79XX_LINUX_HOST_H_ - -int ahd_linux_proc_info(char *, char **, off_t, int, int, int); -int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -int ahd_linux_detect(Scsi_Host_Template *); -int ahd_linux_release(struct Scsi_Host *); -const char *ahd_linux_info(struct Scsi_Host *); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -int ahd_linux_slave_alloc(Scsi_Device *); -int ahd_linux_slave_configure(Scsi_Device *); -void ahd_linux_slave_destroy(Scsi_Device *); -int ahd_linux_biosparam(struct scsi_device*, struct block_device*, - sector_t, int[]); -#else -void ahd_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); -int ahd_linux_biosparam(Disk *, kdev_t, int[]); -#endif -int ahd_linux_bus_reset(Scsi_Cmnd *); -int ahd_linux_dev_reset(Scsi_Cmnd *); -int ahd_linux_abort(Scsi_Cmnd *); - -#if defined(__i386__) -# define AIC79XX_BIOSPARAM ahd_linux_biosparam -#else -# define AIC79XX_BIOSPARAM NULL -#endif - -#if defined BLK_BOUNCE_HIGH -#define AIC79XX_TEMPLATE_HIGHMEM_IO \ - highmem_io: 1, -#else -#define AIC79XX_TEMPLATE_HIGHMEM_IO -#endif - -/* - * Scsi_Host_Template (see hosts.h) for AIC-79xx - some fields - * to do with card config are filled in after the card is detected. - */ -#define AIC79XX_TEMPLATE_CORE \ - proc_info: ahd_linux_proc_info, \ - detect: ahd_linux_detect, \ - release: ahd_linux_release, \ - info: ahd_linux_info, \ - queuecommand: ahd_linux_queue, \ - eh_abort_handler: ahd_linux_abort, \ - eh_device_reset_handler: ahd_linux_dev_reset, \ - eh_bus_reset_handler: ahd_linux_bus_reset, \ - bios_param: AIC79XX_BIOSPARAM, \ - can_queue: AHD_MAX_QUEUE,/* max simultaneous cmds */\ - this_id: -1, /* scsi id of host adapter */\ - sg_tablesize: AHD_NSEG, /* max scatter-gather cmds */\ - cmd_per_lun: 2, /* cmds per lun */\ - present: 0, /* number of 7xxx's present */\ - unchecked_isa_dma: 0, /* no memory DMA restrictions*/\ - AIC79XX_TEMPLATE_HIGHMEM_IO \ - use_clustering: ENABLE_CLUSTERING - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#define AIC79XX { \ - AIC79XX_TEMPLATE_CORE, \ - slave_alloc: ahd_linux_slave_alloc, \ - slave_configure: ahd_linux_slave_configure, \ - slave_destroy: ahd_linux_slave_destroy \ -} -#else -#define AIC79XX { \ - AIC79XX_TEMPLATE_CORE, \ - select_queue_depths: ahd_linux_select_queue_depth, \ - use_new_eh_code: 1 \ -} -#endif -#endif /* _AIC79XX_LINUX_HOST_H_ */ diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index a25e61d9bb60..5f7b427a176e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -1,7 +1,7 @@ /* * Adaptec AIC79xx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#91 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.c#92 $ * * -------------------------------------------------------------------------- * Copyright (c) 1994-2000 Justin T. Gibbs. @@ -549,6 +549,7 @@ static int ahd_linux_next_unit(void); static void ahd_runq_tasklet(unsigned long data); static int ahd_linux_halt(struct notifier_block *nb, u_long event, void *buf); +/****************************** Inlines ***************************************/ static __inline void ahd_schedule_completeq(struct ahd_softc *ahd, struct ahd_cmd *acmd); static __inline void ahd_schedule_runq(struct ahd_softc *ahd); @@ -794,6 +795,531 @@ ahd_linux_map_seg(struct ahd_softc *ahd, struct scb *scb, return (consumed); } +/************************ Host template entry points *************************/ +static int ahd_linux_detect(Scsi_Host_Template *); +static int ahd_linux_release(struct Scsi_Host *); +static const char *ahd_linux_info(struct Scsi_Host *); +static int ahd_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahd_linux_slave_alloc(Scsi_Device *); +static int ahd_linux_slave_configure(Scsi_Device *); +static void ahd_linux_slave_destroy(Scsi_Device *); +static int ahd_linux_biosparam(struct scsi_device*, + struct block_device*, sector_t, int[]); +#else +static void ahd_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +static int ahd_linux_biosparam(Disk *, kdev_t, int[]); +#endif +static int ahd_linux_bus_reset(Scsi_Cmnd *); +static int ahd_linux_dev_reset(Scsi_Cmnd *); +static int ahd_linux_abort(Scsi_Cmnd *); + +/* + * Try to detect an Adaptec 79XX controller. + */ +static int +ahd_linux_detect(Scsi_Host_Template *template) +{ + struct ahd_softc *ahd; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * It is a bug that the upper layer takes + * this lock just prior to calling us. + */ + spin_unlock_irq(&io_request_lock); +#endif + + /* + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. + */ + if (offsetof(struct ahd_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahd_linux_detect: SCSI data structures changed.\n"); + printf("ahd_linux_detect: Unable to attach\n"); + return (0); + } +#ifdef MODULE + /* + * If we've been passed any parameters, process them now. + */ + if (aic79xx) + aic79xx_setup(aic79xx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n" +"aic79xx: to see the proper way to specify options to the aic79xx module\n" +"aic79xx: Specifically, don't use any commas when passing arguments to\n" +"aic79xx: insmod or else it might trash certain memory areas.\n"); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic79xx"; +#else + template->proc_dir = &proc_scsi_aic79xx; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + /* + * We can only map 16MB per-SG + * so create a sector limit of + * "16MB" in 2K sectors. + */ + template->max_sectors = 8192; +#endif + + /* + * Initialize our softc list lock prior to + * probing for any adapters. + */ + ahd_list_lockinit(); + +#ifdef CONFIG_PCI + ahd_linux_pci_probe(template); +#endif + + /* + * Register with the SCSI layer all + * controllers we've found. + */ + found = 0; + TAILQ_FOREACH(ahd, &ahd_tailq, links) { + + if (ahd_linux_register_host(ahd, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic79xx_detect_complete++; + return (found); +} + +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ +static int +ahd_linux_release(struct Scsi_Host * host) +{ + struct ahd_softc *ahd; + u_long l; + + ahd_list_lock(&l); + if (host != NULL) { + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); + if (ahd != NULL) { + u_long s; + + ahd_lock(ahd, &s); + ahd_intr_enable(ahd, FALSE); + ahd_unlock(ahd, &s); + ahd_free(ahd); + } + } + ahd_list_unlock(&l); + return (0); +} + +/* + * Return a string describing the driver. + */ +static const char * +ahd_linux_info(struct Scsi_Host *host) +{ + static char buffer[512]; + char ahd_info[256]; + char *bp; + struct ahd_softc *ahd; + + bp = &buffer[0]; + ahd = *(struct ahd_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev "); + strcat(bp, AIC79XX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahd->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahd_controller_info(ahd, ahd_info); + strcat(bp, ahd_info); + strcat(bp, "\n"); + + return (bp); +} + +/* + * Queue an SCB to the controller. + */ +static int +ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *(struct ahd_softc **)cmd->host->hostdata; + + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; + + ahd_midlayer_entrypoint_lock(ahd, &flags); + + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahd->platform_data->qfrozen != 0 + && AHD_DV_CMD(cmd) == 0) { + + ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahd_linux_queue_cmd_complete(ahd, cmd); + ahd_schedule_completeq(ahd, NULL); + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); + } + dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target, + cmd->lun, /*alloc*/TRUE); + if (dev == NULL) { + ahd_midlayer_entrypoint_unlock(ahd, &flags); + printf("aic79xx_linux_queue: Unable to allocate device!\n"); + return (-ENOMEM); + } + if (cmd->cmd_len > MAX_CDB_LEN) + return (-EINVAL); + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); + dev->flags |= AHD_DEV_ON_RUN_LIST; + ahd_linux_run_device_queues(ahd); + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahd_linux_slave_configure(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + ahd_midlayer_entrypoint_lock(ahd, &flags); + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->scsi_device = device; + } + ahd_linux_device_queue_depth(ahd, dev); + ahd_midlayer_entrypoint_unlock(ahd, &flags); + return (0); +} + +static void +ahd_linux_slave_destroy(Scsi_Device *device) +{ + struct ahd_softc *ahd; + struct ahd_linux_device *dev; + u_long flags; + + ahd = *((struct ahd_softc **)device->host->hostdata); + ahd_midlayer_entrypoint_lock(ahd, &flags); + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/FALSE); + if (dev != NULL) + dev->flags |= AHD_DEV_UNCONFIGURED; + ahd_midlayer_entrypoint_unlock(ahd, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahd_linux_select_queue_depth(struct Scsi_Host * host, + Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + struct ahd_softc *ahd; + u_long flags; + int scbnum; + + ahd = *((struct ahd_softc **)host->hostdata); + ahd_midlayer_entrypoint_lock(ahd, &flags); + scbnum = 0; + for (device = scsi_devs; device != NULL; device = device->next) { + + if (device->host == host) { + struct ahd_linux_device *dev; + + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahd_linux_get_device(ahd, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHD_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahd_linux_device_queue_depth(ahd, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHD_DEV_Q_BASIC + | AHD_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } + } + ahd_midlayer_entrypoint_unlock(ahd, &flags); +} +#endif + +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) +{ + uint8_t *bh; +#else +ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +{ + struct scsi_device *sdev = disk->device; + u_long capacity = disk->capacity; + struct buffer_head *bh; +#endif + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahd_softc *ahd; + + ahd = *((struct ahd_softc **)sdev->host->hostdata); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif + + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); +#endif + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = aic_sector_div(capacity, heads, sectors); + + if (aic79xx_extended != 0) + extended = 1; + else + extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = aic_sector_div(capacity, heads, sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + return (0); +} + +/* + * Abort the current SCSI command(s). + */ +static int +ahd_linux_abort(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + u_long s; +#if NOTYET + struct ahd_cmd *acmd; + int found; +#endif + + ahd = *(struct ahd_softc **)cmd->host->hostdata; +#if NOTYET + int error; + + error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT); + if (error != 0) + printf("aic79xx_abort returns 0x%x\n", error); + return (error); +#else + ahd_midlayer_entrypoint_lock(ahd, &s); +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { + printf("%s: Abort called for cmd %p\n", ahd_name(ahd), cmd); + ahd_dump_card_state(ahd); + } +#endif + ahd_midlayer_entrypoint_unlock(ahd, &s); + return (FAILED); +#endif +} + +/* + * Attempt to send a target reset message to the device that timed out. + */ +static int +ahd_linux_dev_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; +#if NOTYET + struct ahd_cmd *acmd; + u_long s; + int found; +#endif + + ahd = *(struct ahd_softc **)cmd->host->hostdata; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) + printf("%s: Dev reset called for cmd %p\n", + ahd_name(ahd), cmd); +#endif +#if NOTYET + int error; + + error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); + if (error != 0) + printf("aic79xx_dev_reset returns 0x%x\n", error); + return (error); +#else + return (FAILED); +#endif +} + +/* + * Reset the SCSI bus. + */ +static int +ahd_linux_bus_reset(Scsi_Cmnd *cmd) +{ + struct ahd_softc *ahd; + struct ahd_cmd *acmd; + u_long s; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahd = *(struct ahd_softc **)cmd->host->hostdata; +#ifdef AHD_DEBUG + if ((ahd_debug & AHD_SHOW_RECOVERY) != 0); + printf("%s: Bus reset called for cmd %p\n", + ahd_name(ahd), cmd); +#endif + ahd_midlayer_entrypoint_lock(ahd, &s); + found = ahd_reset_channel(ahd, cmd->channel + 'A', + /*initiate reset*/TRUE); + acmd = TAILQ_FIRST(&ahd->platform_data->completeq); + TAILQ_INIT(&ahd->platform_data->completeq); + ahd_midlayer_entrypoint_unlock(ahd, &s); + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahd_name(ahd), found); + + if (acmd != NULL) { + acmd = ahd_linux_run_complete_queue(ahd, acmd); + if (acmd != NULL) { + ahd_midlayer_entrypoint_lock(ahd, &s); + ahd_schedule_completeq(ahd, acmd); + ahd_midlayer_entrypoint_unlock(ahd, &s); + } + } + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return (SUCCESS); +} + +Scsi_Host_Template aic79xx_driver_template = { + .proc_info = ahd_linux_proc_info, + .detect = ahd_linux_detect, + .release = ahd_linux_release, + .info = ahd_linux_info, + .queuecommand = ahd_linux_queue, + .eh_abort_handler = ahd_linux_abort, + .eh_device_reset_handler = ahd_linux_dev_reset, + .eh_bus_reset_handler = ahd_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahd_linux_biosparam, +#endif + .can_queue = AHD_MAX_QUEUE, + .this_id = -1, + .sg_tablesize = AHD_NSEG, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, +#if defined CONFIG_HIGHIO +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .slave_configure = ahd_linux_slave_configure, + .slave_destroy = ahd_linux_slave_destroy, +#else + .select_queue_depths = ahd_linux_select_queue_depth, + .use_new_eh_code = 1, +#endif +}; + +#define driver_template aic79xx_driver_template +#include "scsi_module.c" /**************************** Tasklet Handler *********************************/ static void @@ -1433,90 +1959,6 @@ __setup("aic79xx=", aic79xx_setup); int aic79xx_verbose; -/* - * Try to detect an Adaptec 79XX controller. - */ -int -ahd_linux_detect(Scsi_Host_Template *template) -{ - struct ahd_softc *ahd; - int found; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); -#endif - - /* - * Sanity checking of Linux SCSI data structures so - * that some of our hacks^H^H^H^H^Hassumptions aren't - * violated. - */ - if (offsetof(struct ahd_cmd_internal, end) - > offsetof(struct scsi_cmnd, host_scribble)) { - printf("ahd_linux_detect: SCSI data structures changed.\n"); - printf("ahd_linux_detect: Unable to attach\n"); - return (0); - } -#ifdef MODULE - /* - * If we've been passed any parameters, process them now. - */ - if (aic79xx) - aic79xx_setup(aic79xx); - if (dummy_buffer[0] != 'P') - printk(KERN_WARNING -"aic79xx: Please read the file /usr/src/linux/drivers/scsi/README.aic79xx\n" -"aic79xx: to see the proper way to specify options to the aic79xx module\n" -"aic79xx: Specifically, don't use any commas when passing arguments to\n" -"aic79xx: insmod or else it might trash certain memory areas.\n"); -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) - template->proc_name = "aic79xx"; -#else - template->proc_dir = &proc_scsi_aic79xx; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - template->max_sectors = 8192; -#endif - - /* - * Initialize our softc list lock prior to - * probing for any adapters. - */ - ahd_list_lockinit(); - -#ifdef CONFIG_PCI - ahd_linux_pci_probe(template); -#endif - - /* - * Register with the SCSI layer all - * controllers we've found. - */ - found = 0; - TAILQ_FOREACH(ahd, &ahd_tailq, links) { - - if (ahd_linux_register_host(ahd, template) == 0) - found++; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - aic79xx_detect_complete++; - return (found); -} - int ahd_linux_register_host(struct ahd_softc *ahd, Scsi_Host_Template *template) { @@ -3285,112 +3727,6 @@ ahd_linux_generate_dv_pattern(struct ahd_linux_target *targ) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -int -ahd_linux_slave_alloc(Scsi_Device *device) -{ - /* - * Nothing to be done for now. - */ - return (0); -} - -int -ahd_linux_slave_configure(Scsi_Device *device) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *((struct ahd_softc **)device->host->hostdata); - ahd_midlayer_entrypoint_lock(ahd, &flags); - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHD_DEV_UNCONFIGURED; - dev->scsi_device = device; - } - ahd_linux_device_queue_depth(ahd, dev); - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); -} - -void -ahd_linux_slave_destroy(Scsi_Device *device) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *((struct ahd_softc **)device->host->hostdata); - ahd_midlayer_entrypoint_lock(ahd, &flags); - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/FALSE); - if (dev != NULL) - dev->flags |= AHD_DEV_UNCONFIGURED; - ahd_midlayer_entrypoint_unlock(ahd, &flags); -} -#else -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ -void -ahd_linux_select_queue_depth(struct Scsi_Host * host, - Scsi_Device * scsi_devs) -{ - Scsi_Device *device; - struct ahd_softc *ahd; - u_long flags; - int scbnum; - - ahd = *((struct ahd_softc **)host->hostdata); - ahd_midlayer_entrypoint_lock(ahd, &flags); - scbnum = 0; - for (device = scsi_devs; device != NULL; device = device->next) { - - if (device->host == host) { - struct ahd_linux_device *dev; - - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahd_linux_get_device(ahd, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHD_DEV_UNCONFIGURED; - dev->scsi_device = device; - ahd_linux_device_queue_depth(ahd, dev); - device->queue_depth = dev->openings - + dev->active; - if ((dev->flags & (AHD_DEV_Q_BASIC - | AHD_DEV_Q_TAGGED)) == 0) { - /* - * We allow the OS to queue 2 untagged - * transactions to us at any time even - * though we can only execute them - * serially on the controller/device. - * This should remove some latency. - */ - device->queue_depth = 2; - } - } - } - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); -} -#endif - static u_int ahd_linux_user_tagdepth(struct ahd_softc *ahd, struct ahd_devinfo *devinfo) { @@ -3484,60 +3820,6 @@ ahd_linux_device_queue_depth(struct ahd_softc *ahd, } } -/* - * Queue an SCB to the controller. - */ -int -ahd_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) -{ - struct ahd_softc *ahd; - struct ahd_linux_device *dev; - u_long flags; - - ahd = *(struct ahd_softc **)cmd->host->hostdata; - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - ahd_midlayer_entrypoint_lock(ahd, &flags); - - /* - * Close the race of a command that was in the process of - * being queued to us just as our simq was frozen. Let - * DV commands through so long as we are only frozen to - * perform DV. - */ - if (ahd->platform_data->qfrozen != 0 - && AHD_DV_CMD(cmd) == 0) { - - ahd_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); - ahd_linux_queue_cmd_complete(ahd, cmd); - ahd_schedule_completeq(ahd, NULL); - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); - } - dev = ahd_linux_get_device(ahd, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); - if (dev == NULL) { - ahd_midlayer_entrypoint_unlock(ahd, &flags); - printf("aic79xx_linux_queue: Unable to allocate device!\n"); - return (-ENOMEM); - } - if (cmd->cmd_len > MAX_CDB_LEN) - return (-EINVAL); - cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahd_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHD_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahd->platform_data->device_runq, dev, links); - dev->flags |= AHD_DEV_ON_RUN_LIST; - ahd_linux_run_device_queues(ahd); - } - ahd_midlayer_entrypoint_unlock(ahd, &flags); - return (0); -} - static void ahd_linux_run_device_queue(struct ahd_softc *ahd, struct ahd_linux_device *dev) { @@ -3863,34 +4145,6 @@ ahd_linux_free_device(struct ahd_softc *ahd, struct ahd_linux_device *dev) ahd_linux_free_target(ahd, targ); } -/* - * Return a string describing the driver. - */ -const char * -ahd_linux_info(struct Scsi_Host *host) -{ - static char buffer[512]; - char ahd_info[256]; - char *bp; - struct ahd_softc *ahd; - - bp = &buffer[0]; - ahd = *(struct ahd_softc **)host->hostdata; - memset(bp, 0, sizeof(buffer)); - strcpy(bp, "Adaptec AIC79XX PCI-X SCSI HBA DRIVER, Rev "); - strcat(bp, AIC79XX_DRIVER_VERSION); - strcat(bp, "\n"); - strcat(bp, " <"); - strcat(bp, ahd->description); - strcat(bp, ">\n"); - strcat(bp, " "); - ahd_controller_info(ahd, ahd_info); - strcat(bp, ahd_info); - strcat(bp, "\n"); - - return (bp); -} - void ahd_send_async(struct ahd_softc *ahd, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -4861,218 +5115,6 @@ ahd_linux_dev_timed_unfreeze(u_long arg) ahd_unlock(ahd, &s); } -/* - * Abort the current SCSI command(s). - */ -int -ahd_linux_abort(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; - u_long s; -#if NOTYET - struct ahd_cmd *acmd; - int found; -#endif - - ahd = *(struct ahd_softc **)cmd->host->hostdata; -#if NOTYET - int error; - - error = ahd_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) - printf("aic79xx_abort returns 0x%x\n", error); - return (error); -#else - ahd_midlayer_entrypoint_lock(ahd, &s); -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) { - printf("%s: Abort called for cmd %p\n", ahd_name(ahd), cmd); - ahd_dump_card_state(ahd); - } -#endif - ahd_midlayer_entrypoint_unlock(ahd, &s); - return (FAILED); -#endif -} - -/* - * Attempt to send a target reset message to the device that timed out. - */ -int -ahd_linux_dev_reset(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; -#if NOTYET - struct ahd_cmd *acmd; - u_long s; - int found; -#endif - - ahd = *(struct ahd_softc **)cmd->host->hostdata; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0) - printf("%s: Dev reset called for cmd %p\n", - ahd_name(ahd), cmd); -#endif -#if NOTYET - int error; - - error = ahd_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) - printf("aic79xx_dev_reset returns 0x%x\n", error); - return (error); -#else - return (FAILED); -#endif -} - -/* - * Reset the SCSI bus. - */ -int -ahd_linux_bus_reset(Scsi_Cmnd *cmd) -{ - struct ahd_softc *ahd; - struct ahd_cmd *acmd; - u_long s; - int found; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahd = *(struct ahd_softc **)cmd->host->hostdata; -#ifdef AHD_DEBUG - if ((ahd_debug & AHD_SHOW_RECOVERY) != 0); - printf("%s: Bus reset called for cmd %p\n", - ahd_name(ahd), cmd); -#endif - ahd_midlayer_entrypoint_lock(ahd, &s); - found = ahd_reset_channel(ahd, cmd->channel + 'A', - /*initiate reset*/TRUE); - acmd = TAILQ_FIRST(&ahd->platform_data->completeq); - TAILQ_INIT(&ahd->platform_data->completeq); - ahd_midlayer_entrypoint_unlock(ahd, &s); - if (bootverbose) - printf("%s: SCSI bus reset delivered. " - "%d SCBs aborted.\n", ahd_name(ahd), found); - - if (acmd != NULL) { - acmd = ahd_linux_run_complete_queue(ahd, acmd); - if (acmd != NULL) { - ahd_midlayer_entrypoint_lock(ahd, &s); - ahd_schedule_completeq(ahd, acmd); - ahd_midlayer_entrypoint_unlock(ahd, &s); - } - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - return (SUCCESS); -} - -/* - * Return the disk geometry for the given SCSI device. - */ -int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -ahd_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int geom[]) -#else -ahd_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -#endif -{ - int heads; - int sectors; - int cylinders; - int ret; - int extended; - struct ahd_softc *ahd; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - uint8_t *bh; -#else - u_long capacity; - struct buffer_head *bh; - - capacity = disk->capacity; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahd = *((struct ahd_softc **)sdev->host->hostdata); -#else - ahd = *((struct ahd_softc **)disk->device->host->hostdata); -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - bh = scsi_bios_ptable(bdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); -#else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); -#endif - - if (bh) { - ret = scsi_partsize(bh, capacity, - &geom[2], &geom[0], &geom[1]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - kfree(bh); -#else - brelse(bh); -#endif - if (ret != -1) - return (ret); - } - heads = 64; - sectors = 32; - cylinders = capacity / (heads * sectors); - - if (aic79xx_extended != 0) - extended = 1; - else - extended = (ahd->flags & AHD_EXTENDED_TRANS_A) != 0; - if (extended && cylinders >= 1024) { - heads = 255; - sectors = 63; - cylinders = capacity / (heads * sectors); - } - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - return (0); -} - -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -int -ahd_linux_release(struct Scsi_Host * host) -{ - struct ahd_softc *ahd; - u_long l; - - ahd_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahd = ahd_find_softc(*(struct ahd_softc **)host->hostdata); - if (ahd != NULL) { - u_long s; - - ahd_lock(ahd, &s); - ahd_intr_enable(ahd, FALSE); - ahd_unlock(ahd, &s); - ahd_free(ahd); - } - } - ahd_list_unlock(&l); - return (0); -} - void ahd_platform_dump_card_state(struct ahd_softc *ahd) { @@ -5103,9 +5145,3 @@ ahd_platform_dump_card_state(struct ahd_softc *ahd) } } } - -#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static Scsi_Host_Template driver_template = AIC79XX; -Scsi_Host_Template *aic79xx_driver_template = &driver_template; -#include "scsi_module.c" -#endif diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 3894b34ffe1a..6600f768098a 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#87 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm.h#88 $ * */ #ifndef _AIC79XX_LINUX_H_ @@ -291,7 +291,7 @@ ahd_scb_timer_reset(struct scb *scb, u_int usec) #include <linux/smp.h> #endif -#define AIC79XX_DRIVER_VERSION "1.3.0.ALPHA2" +#define AIC79XX_DRIVER_VERSION "1.3.0.ALPHA3" /**************************** Front End Queues ********************************/ /* diff --git a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c index e91270b8741c..fe598eba390d 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm_pci.c @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#17 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic79xx_osm_pci.c#18 $ */ #include "aic79xx_osm.h" @@ -181,7 +181,7 @@ ahd_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahd); if (aic79xx_detect_complete) - ahd_linux_register_host(ahd, aic79xx_driver_template); + ahd_linux_register_host(ahd, &aic79xx_driver_template); #endif return (0); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_host.h b/drivers/scsi/aic7xxx/aic7xxx_host.h deleted file mode 100644 index 4fe61e194441..000000000000 --- a/drivers/scsi/aic7xxx/aic7xxx_host.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Adaptec AIC7xxx device driver host template for Linux. - * - * Copyright (c) 2000-2001 Adaptec Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification. - * 2. Redistributions in binary form must reproduce at minimum a disclaimer - * substantially similar to the "NO WARRANTY" disclaimer below - * ("Disclaimer") and any redistribution must be conditioned upon - * including a substantially similar Disclaimer requirement for further - * binary redistribution. - * 3. Neither the names of the above-listed copyright holders nor the names - * of any contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * Alternatively, this software may be distributed under the terms of the - * GNU General Public License ("GPL") version 2 as published by the Free - * Software Foundation. - * - * NO WARRANTY - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_host.h#13 $ - */ - -#ifndef _AIC7XXX_HOST_H_ -#define _AIC7XXX_HOST_H_ - -int ahc_linux_proc_info(char *, char **, off_t, int, int, int); -int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); -int ahc_linux_detect(Scsi_Host_Template *); -int ahc_linux_release(struct Scsi_Host *); -const char *ahc_linux_info(struct Scsi_Host *); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -int ahc_linux_slave_alloc(Scsi_Device *); -int ahc_linux_slave_configure(Scsi_Device *); -void ahc_linux_slave_destroy(Scsi_Device *); -int ahd_linux_biosparam(struct scsi_device*, struct block_device*, - sector_t, int[]); -#else -void ahc_linux_select_queue_depth(struct Scsi_Host *host, - Scsi_Device *scsi_devs); -int ahc_linux_biosparam(Disk *, kdev_t, int[]); -#endif -int ahc_linux_bus_reset(Scsi_Cmnd *); -int ahc_linux_dev_reset(Scsi_Cmnd *); -int ahc_linux_abort(Scsi_Cmnd *); - -#if defined(__i386__) -# define AIC7XXX_BIOSPARAM ahc_linux_biosparam -#else -# define AIC7XXX_BIOSPARAM NULL -#endif - -#if defined BLK_BOUNCE_HIGH -#define AIC7XXX_TEMPLATE_HIGHMEM_IO \ - highmem_io: 1, -#else -#define AIC7XXX_TEMPLATE_HIGHMEM_IO -#endif - -/* - * Scsi_Host_Template (see hosts.h) for AIC-7xxx - some fields - * to do with card config are filled in after the card is detected. - */ -#define AIC7XXX_TEMPLATE_CORE \ - proc_info: ahc_linux_proc_info, \ - detect: ahc_linux_detect, \ - release: ahc_linux_release, \ - info: ahc_linux_info, \ - queuecommand: ahc_linux_queue, \ - eh_abort_handler: ahc_linux_abort, \ - eh_device_reset_handler: ahc_linux_dev_reset, \ - eh_bus_reset_handler: ahc_linux_bus_reset, \ - bios_param: AIC7XXX_BIOSPARAM, \ - can_queue: AHC_MAX_QUEUE,/* max simultaneous cmds */\ - this_id: -1, /* scsi id of host adapter */\ - sg_tablesize: AHC_NSEG, /* max scatter-gather cmds */\ - cmd_per_lun: 2, /* cmds per lun */\ - present: 0, /* number of 7xxx's present */\ - unchecked_isa_dma: 0, /* no memory DMA restrictions*/\ - AIC7XXX_TEMPLATE_HIGHMEM_IO \ - use_clustering: ENABLE_CLUSTERING - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -#define AIC7XXX { \ - AIC7XXX_TEMPLATE_CORE, \ - slave_alloc: ahc_linux_slave_alloc, \ - slave_configure: ahc_linux_slave_configure, \ - slave_destroy: ahc_linux_slave_destroy \ -} -#else -#define AIC7XXX { \ - AIC7XXX_TEMPLATE_CORE, \ - select_queue_depths: ahc_linux_select_queue_depth, \ - use_new_eh_code: 1 \ -} -#endif - -#endif /* _AIC7XXX_HOST_H_ */ diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 95f3974e25fb..c2d9cf831621 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -1,7 +1,7 @@ /* * Adaptec AIC7xxx device driver for Linux. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#159 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.c#160 $ * * Copyright (c) 1994 John Aycock * The University of Calgary Department of Computer Science. @@ -576,12 +576,12 @@ static void ahc_linux_run_device_queue(struct ahc_softc*, static void ahc_linux_setup_tag_info(char *p, char *end, char *s); static void ahc_linux_setup_tag_info_global(char *p); static void ahc_linux_setup_dv(char *p, char *end, char *s); -static int ahc_linux_next_unit(void); +static int ahc_linux_next_unit(void); static void ahc_runq_tasklet(unsigned long data); -static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static int ahc_linux_halt(struct notifier_block *nb, u_long event, void *buf); +static void ahc_schedule_completeq(struct ahc_softc *ahc, struct ahc_cmd *acmd); -static void ahc_schedule_completeq(struct ahc_softc *ahc, - struct ahc_cmd *acmd); +/********************************* Inlines ************************************/ static __inline void ahc_schedule_runq(struct ahc_softc *ahc); static __inline struct ahc_linux_device* ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, @@ -806,6 +806,510 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, return (consumed); } +/************************ Host template entry points *************************/ +static int ahc_linux_detect(Scsi_Host_Template *); +static int ahc_linux_release(struct Scsi_Host *); +static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); +static const char *ahc_linux_info(struct Scsi_Host *); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int ahc_linux_slave_alloc(Scsi_Device *); +static int ahc_linux_slave_configure(Scsi_Device *); +static void ahc_linux_slave_destroy(Scsi_Device *); +static int ahd_linux_biosparam(struct scsi_device*, + struct block_device*, + sector_t, int[]); +#else +static void ahc_linux_select_queue_depth(struct Scsi_Host *host, + Scsi_Device *scsi_devs); +static int ahc_linux_biosparam(Disk *, kdev_t, int[]); +#endif +static int ahc_linux_bus_reset(Scsi_Cmnd *); +static int ahc_linux_dev_reset(Scsi_Cmnd *); +static int ahc_linux_abort(Scsi_Cmnd *); + +/* + * Try to detect an Adaptec 7XXX controller. + */ +static int +ahc_linux_detect(Scsi_Host_Template *template) +{ + struct ahc_softc *ahc; + int found; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + /* + * It is a bug that the upper layer takes + * this lock just prior to calling us. + */ + spin_unlock_irq(&io_request_lock); +#endif + + /* + * Sanity checking of Linux SCSI data structures so + * that some of our hacks^H^H^H^H^Hassumptions aren't + * violated. + */ + if (offsetof(struct ahc_cmd_internal, end) + > offsetof(struct scsi_cmnd, host_scribble)) { + printf("ahc_linux_detect: SCSI data structures changed.\n"); + printf("ahc_linux_detect: Unable to attach\n"); + return (0); + } +#ifdef MODULE + /* + * If we've been passed any parameters, process them now. + */ + if (aic7xxx) + aic7xxx_setup(aic7xxx); + if (dummy_buffer[0] != 'P') + printk(KERN_WARNING +"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" +"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" +"aic7xxx: Specifically, don't use any commas when passing arguments to\n" +"aic7xxx: insmod or else it might trash certain memory areas.\n"); +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) + template->proc_name = "aic7xxx"; +#else + template->proc_dir = &proc_scsi_aic7xxx; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) + /* + * We can only map 16MB per-SG + * so create a sector limit of + * "16MB" in 2K sectors. + */ + template->max_sectors = 8192; +#endif + + /* + * Initialize our softc list lock prior to + * probing for any adapters. + */ + ahc_list_lockinit(); + +#ifdef CONFIG_PCI + ahc_linux_pci_probe(template); +#endif + + if (aic7xxx_no_probe == 0) + aic7770_linux_probe(template); + + /* + * Register with the SCSI layer all + * controllers we've found. + */ + found = 0; + TAILQ_FOREACH(ahc, &ahc_tailq, links) { + + if (ahc_linux_register_host(ahc, template) == 0) + found++; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + aic7xxx_detect_complete++; + return (found); +} + +/* + * Free the passed in Scsi_Host memory structures prior to unloading the + * module. + */ +int +ahc_linux_release(struct Scsi_Host * host) +{ + struct ahc_softc *ahc; + u_long l; + + ahc_list_lock(&l); + if (host != NULL) { + + /* + * We should be able to just perform + * the free directly, but check our + * list for extra sanity. + */ + ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); + if (ahc != NULL) { + u_long s; + + ahc_lock(ahc, &s); + ahc_intr_enable(ahc, FALSE); + ahc_unlock(ahc, &s); + ahc_free(ahc); + } + } + ahc_list_unlock(&l); + return (0); +} + +/* + * Return a string describing the driver. + */ +static const char * +ahc_linux_info(struct Scsi_Host *host) +{ + static char buffer[512]; + char ahc_info[256]; + char *bp; + struct ahc_softc *ahc; + + bp = &buffer[0]; + ahc = *(struct ahc_softc **)host->hostdata; + memset(bp, 0, sizeof(buffer)); + strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); + strcat(bp, AIC7XXX_DRIVER_VERSION); + strcat(bp, "\n"); + strcat(bp, " <"); + strcat(bp, ahc->description); + strcat(bp, ">\n"); + strcat(bp, " "); + ahc_controller_info(ahc, ahc_info); + strcat(bp, ahc_info); + strcat(bp, "\n"); + + return (bp); +} + +/* + * Queue an SCB to the controller. + */ +static int +ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; + + ahc = *(struct ahc_softc **)cmd->host->hostdata; + + /* + * Save the callback on completion function. + */ + cmd->scsi_done = scsi_done; + + ahc_midlayer_entrypoint_lock(ahc, &flags); + + /* + * Close the race of a command that was in the process of + * being queued to us just as our simq was frozen. Let + * DV commands through so long as we are only frozen to + * perform DV. + */ + if (ahc->platform_data->qfrozen != 0 + && AHC_DV_CMD(cmd) == 0) { + + ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); + ahc_linux_queue_cmd_complete(ahc, cmd); + ahc_schedule_completeq(ahc, NULL); + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); + } + dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, + cmd->lun, /*alloc*/TRUE); + if (dev == NULL) { + ahc_midlayer_entrypoint_unlock(ahc, &flags); + printf("aic7xxx_linux_queue: Unable to allocate device!\n"); + return (-ENOMEM); + } + cmd->result = CAM_REQ_INPROG << 16; + TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); + if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { + TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); + dev->flags |= AHC_DEV_ON_RUN_LIST; + ahc_linux_run_device_queues(ahc); + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +static int +ahc_linux_slave_alloc(Scsi_Device *device) +{ + /* + * Nothing to be done for now. + */ + return (0); +} + +static int +ahc_linux_slave_configure(Scsi_Device *device) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; + + ahc = *((struct ahc_softc **)device->host->hostdata); + ahc_midlayer_entrypoint_lock(ahc, &flags); + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + } + ahc_linux_device_queue_depth(ahc, dev); + ahc_midlayer_entrypoint_unlock(ahc, &flags); + return (0); +} + +static void +ahc_linux_slave_destroy(Scsi_Device *device) +{ + struct ahc_softc *ahc; + struct ahc_linux_device *dev; + u_long flags; + + ahc = *((struct ahc_softc **)device->host->hostdata); + ahc_midlayer_entrypoint_lock(ahc, &flags); + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/FALSE); + if (dev != NULL) + dev->flags |= AHC_DEV_UNCONFIGURED; + ahc_midlayer_entrypoint_unlock(ahc, &flags); +} +#else +/* + * Sets the queue depth for each SCSI device hanging + * off the input host adapter. + */ +static void +ahc_linux_select_queue_depth(struct Scsi_Host * host, + Scsi_Device * scsi_devs) +{ + Scsi_Device *device; + struct ahc_softc *ahc; + u_long flags; + + ahc = *((struct ahc_softc **)host->hostdata); + ahc_midlayer_entrypoint_lock(ahc, &flags); + for (device = scsi_devs; device != NULL; device = device->next) { + if (device->host == host) { + struct ahc_linux_device *dev; + + /* + * Since Linux has attached to the device, configure + * it so we don't free and allocate the device + * structure on every command. + */ + dev = ahc_linux_get_device(ahc, device->channel, + device->id, device->lun, + /*alloc*/TRUE); + if (dev != NULL) { + dev->flags &= ~AHC_DEV_UNCONFIGURED; + dev->scsi_device = device; + ahc_linux_device_queue_depth(ahc, dev); + device->queue_depth = dev->openings + + dev->active; + if ((dev->flags & (AHC_DEV_Q_BASIC + | AHC_DEV_Q_TAGGED)) == 0) { + /* + * We allow the OS to queue 2 untagged + * transactions to us at any time even + * though we can only execute them + * serially on the controller/device. + * This should remove some latency. + */ + device->queue_depth = 2; + } + } + } + } + ahc_midlayer_entrypoint_unlock(ahc, &flags); +} +#endif + +/* + * Return the disk geometry for the given SCSI device. + */ +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) +ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, + sector_t capacity, int geom[]) +#else +ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) +#endif +{ + int heads; + int sectors; + int cylinders; + int ret; + int extended; + struct ahc_softc *ahc; + u_int channel; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + uint8_t *bh; + + channel = sdev->channel; +#else + u_long capacity; + struct buffer_head *bh; + + capacity = disk->capacity; + channel = disk->device->channel; +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + ahc = *((struct ahc_softc **)sdev->host->hostdata); +#else + ahc = *((struct ahc_softc **)disk->device->host->hostdata); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + bh = scsi_bios_ptable(bdev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); +#else + bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); +#endif + + if (bh) { + ret = scsi_partsize(bh, capacity, + &geom[2], &geom[0], &geom[1]); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + kfree(bh); +#else + brelse(bh); +#endif + if (ret != -1) + return (ret); + } + heads = 64; + sectors = 32; + cylinders = capacity / (heads * sectors); + + if (aic7xxx_extended != 0) + extended = 1; + else if (channel == 0) + extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; + else + extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; + if (extended && cylinders >= 1024) { + heads = 255; + sectors = 63; + cylinders = capacity / (heads * sectors); + } + geom[0] = heads; + geom[1] = sectors; + geom[2] = cylinders; + return (0); +} + +/* + * Abort the current SCSI command(s). + */ +static int +ahc_linux_abort(Scsi_Cmnd *cmd) +{ + int error; + + error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); + if (error != 0) + printf("aic7xxx_abort returns 0x%x\n", error); + return (error); +} + +/* + * Attempt to send a target reset message to the device that timed out. + */ +static int +ahc_linux_dev_reset(Scsi_Cmnd *cmd) +{ + int error; + + error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); + if (error != 0) + printf("aic7xxx_dev_reset returns 0x%x\n", error); + return (error); +} + +/* + * Reset the SCSI bus. + */ +static int +ahc_linux_bus_reset(Scsi_Cmnd *cmd) +{ + struct ahc_softc *ahc; + struct ahc_cmd *acmd; + u_long s; + int found; + + ahc = *(struct ahc_softc **)cmd->host->hostdata; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_unlock_irq(&io_request_lock); +#endif + ahc_midlayer_entrypoint_lock(ahc, &s); + found = ahc_reset_channel(ahc, cmd->channel + 'A', + /*initiate reset*/TRUE); + acmd = TAILQ_FIRST(&ahc->platform_data->completeq); + TAILQ_INIT(&ahc->platform_data->completeq); + ahc_midlayer_entrypoint_unlock(ahc, &s); + if (bootverbose) + printf("%s: SCSI bus reset delivered. " + "%d SCBs aborted.\n", ahc_name(ahc), found); + + if (acmd != NULL) { + acmd = ahc_linux_run_complete_queue(ahc, acmd); + if (acmd != NULL) { + ahc_midlayer_entrypoint_lock(ahc, &s); + ahc_schedule_completeq(ahc, acmd); + ahc_midlayer_entrypoint_unlock(ahc, &s); + } + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) + spin_lock_irq(&io_request_lock); +#endif + return SUCCESS; +} + +Scsi_Host_Template aic7xxx_driver_template = { + .proc_info = ahc_linux_proc_info, + .detect = ahc_linux_detect, + .release = ahc_linux_release, + .info = ahc_linux_info, + .queuecommand = ahc_linux_queue, + .eh_abort_handler = ahc_linux_abort, + .eh_device_reset_handler = ahc_linux_dev_reset, + .eh_bus_reset_handler = ahc_linux_bus_reset, +#if defined(__i386__) + .bios_param = ahc_linux_biosparam, +#endif + .can_queue = AHC_MAX_QUEUE, + .this_id = -1, + .sg_tablesize = AHC_NSEG, + .cmd_per_lun = 2, + .use_clustering = ENABLE_CLUSTERING, +#if defined CONFIG_HIGHIO +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) +/* Assume RedHat Distribution with its different HIGHIO conventions. */ + .can_dma_32 = 1, + .single_sg_okay = 1, +#else + .highmem_io = 1, +#endif +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + .slave_configure = ahc_linux_slave_configure, + .slave_destroy = ahc_linux_slave_destroy, +#else + .select_queue_depths = ahc_linux_select_queue_depth, + .use_new_eh_code = 1, +#endif +}; + +#define driver_template aic7xxx_driver_template +#include "scsi_module.c" + /**************************** Tasklet Handler *********************************/ static void @@ -1317,93 +1821,6 @@ __setup("aic7xxx=", aic7xxx_setup); int aic7xxx_verbose; -/* - * Try to detect an Adaptec 7XXX controller. - */ -int -ahc_linux_detect(Scsi_Host_Template *template) -{ - struct ahc_softc *ahc; - int found; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - /* - * It is a bug that the upper layer takes - * this lock just prior to calling us. - */ - spin_unlock_irq(&io_request_lock); -#endif - - /* - * Sanity checking of Linux SCSI data structures so - * that some of our hacks^H^H^H^H^Hassumptions aren't - * violated. - */ - if (offsetof(struct ahc_cmd_internal, end) - > offsetof(struct scsi_cmnd, host_scribble)) { - printf("ahc_linux_detect: SCSI data structures changed.\n"); - printf("ahc_linux_detect: Unable to attach\n"); - return (0); - } -#ifdef MODULE - /* - * If we've been passed any parameters, process them now. - */ - if (aic7xxx) - aic7xxx_setup(aic7xxx); - if (dummy_buffer[0] != 'P') - printk(KERN_WARNING -"aic7xxx: Please read the file /usr/src/linux/drivers/scsi/README.aic7xxx\n" -"aic7xxx: to see the proper way to specify options to the aic7xxx module\n" -"aic7xxx: Specifically, don't use any commas when passing arguments to\n" -"aic7xxx: insmod or else it might trash certain memory areas.\n"); -#endif - -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,0) - template->proc_name = "aic7xxx"; -#else - template->proc_dir = &proc_scsi_aic7xxx; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) - /* - * We can only map 16MB per-SG - * so create a sector limit of - * "16MB" in 2K sectors. - */ - template->max_sectors = 8192; -#endif - - /* - * Initialize our softc list lock prior to - * probing for any adapters. - */ - ahc_list_lockinit(); - -#ifdef CONFIG_PCI - ahc_linux_pci_probe(template); -#endif - - if (aic7xxx_no_probe == 0) - aic7770_linux_probe(template); - - /* - * Register with the SCSI layer all - * controllers we've found. - */ - found = 0; - TAILQ_FOREACH(ahc, &ahc_tailq, links) { - - if (ahc_linux_register_host(ahc, template) == 0) - found++; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - aic7xxx_detect_complete++; - return (found); -} - int ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) { @@ -3194,109 +3611,6 @@ ahc_linux_generate_dv_pattern(struct ahc_linux_target *targ) } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -int -ahc_linux_slave_alloc(Scsi_Device *device) -{ - /* - * Nothing to be done for now. - */ - return (0); -} - -int -ahc_linux_slave_configure(Scsi_Device *device) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = *((struct ahc_softc **)device->host->hostdata); - ahc_midlayer_entrypoint_lock(ahc, &flags); - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHC_DEV_UNCONFIGURED; - dev->scsi_device = device; - } - ahc_linux_device_queue_depth(ahc, dev); - ahc_midlayer_entrypoint_unlock(ahc, &flags); - return (0); -} - -void -ahc_linux_slave_destroy(Scsi_Device *device) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = *((struct ahc_softc **)device->host->hostdata); - ahc_midlayer_entrypoint_lock(ahc, &flags); - dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/FALSE); - if (dev != NULL) - dev->flags |= AHC_DEV_UNCONFIGURED; - ahc_midlayer_entrypoint_unlock(ahc, &flags); -} -#else -/* - * Sets the queue depth for each SCSI device hanging - * off the input host adapter. - */ -void -ahc_linux_select_queue_depth(struct Scsi_Host * host, - Scsi_Device * scsi_devs) -{ - Scsi_Device *device; - struct ahc_softc *ahc; - u_long flags; - - ahc = *((struct ahc_softc **)host->hostdata); - ahc_midlayer_entrypoint_lock(ahc, &flags); - for (device = scsi_devs; device != NULL; device = device->next) { - if (device->host == host) { - struct ahc_linux_device *dev; - - /* - * Since Linux has attached to the device, configure - * it so we don't free and allocate the device - * structure on every command. - */ - dev = ahc_linux_get_device(ahc, device->channel, - device->id, device->lun, - /*alloc*/TRUE); - if (dev != NULL) { - dev->flags &= ~AHC_DEV_UNCONFIGURED; - dev->scsi_device = device; - ahc_linux_device_queue_depth(ahc, dev); - device->queue_depth = dev->openings - + dev->active; - if ((dev->flags & (AHC_DEV_Q_BASIC - | AHC_DEV_Q_TAGGED)) == 0) { - /* - * We allow the OS to queue 2 untagged - * transactions to us at any time even - * though we can only execute them - * serially on the controller/device. - * This should remove some latency. - */ - device->queue_depth = 2; - } - } - } - } - ahc_midlayer_entrypoint_unlock(ahc, &flags); -} -#endif - static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) { @@ -3400,58 +3714,6 @@ ahc_linux_device_queue_depth(struct ahc_softc *ahc, } } -/* - * Queue an SCB to the controller. - */ -int -ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) -{ - struct ahc_softc *ahc; - struct ahc_linux_device *dev; - u_long flags; - - ahc = *(struct ahc_softc **)cmd->host->hostdata; - - /* - * Save the callback on completion function. - */ - cmd->scsi_done = scsi_done; - - ahc_midlayer_entrypoint_lock(ahc, &flags); - - /* - * Close the race of a command that was in the process of - * being queued to us just as our simq was frozen. Let - * DV commands through so long as we are only frozen to - * perform DV. - */ - if (ahc->platform_data->qfrozen != 0 - && AHC_DV_CMD(cmd) == 0) { - - ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); - ahc_linux_queue_cmd_complete(ahc, cmd); - ahc_schedule_completeq(ahc, NULL); - ahc_midlayer_entrypoint_unlock(ahc, &flags); - return (0); - } - dev = ahc_linux_get_device(ahc, cmd->channel, cmd->target, - cmd->lun, /*alloc*/TRUE); - if (dev == NULL) { - ahc_midlayer_entrypoint_unlock(ahc, &flags); - printf("aic7xxx_linux_queue: Unable to allocate device!\n"); - return (-ENOMEM); - } - cmd->result = CAM_REQ_INPROG << 16; - TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); - if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { - TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); - dev->flags |= AHC_DEV_ON_RUN_LIST; - ahc_linux_run_device_queues(ahc); - } - ahc_midlayer_entrypoint_unlock(ahc, &flags); - return (0); -} - static void ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev) { @@ -3843,34 +4105,6 @@ ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) ahc_linux_free_target(ahc, targ); } -/* - * Return a string describing the driver. - */ -const char * -ahc_linux_info(struct Scsi_Host *host) -{ - static char buffer[512]; - char ahc_info[256]; - char *bp; - struct ahc_softc *ahc; - - bp = &buffer[0]; - ahc = *(struct ahc_softc **)host->hostdata; - memset(bp, 0, sizeof(buffer)); - strcpy(bp, "Adaptec AIC7XXX EISA/VLB/PCI SCSI HBA DRIVER, Rev "); - strcat(bp, AIC7XXX_DRIVER_VERSION); - strcat(bp, "\n"); - strcat(bp, " <"); - strcat(bp, ahc->description); - strcat(bp, ">\n"); - strcat(bp, " "); - ahc_controller_info(ahc, ahc_info); - strcat(bp, ahc_info); - strcat(bp, "\n"); - - return (bp); -} - void ahc_send_async(struct ahc_softc *ahc, char channel, u_int target, u_int lun, ac_code code, void *arg) @@ -4852,181 +5086,6 @@ done: return (retval); } -/* - * Abort the current SCSI command(s). - */ -int -ahc_linux_abort(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT); - if (error != 0) - printf("aic7xxx_abort returns 0x%x\n", error); - return (error); -} - -/* - * Attempt to send a target reset message to the device that timed out. - */ -int -ahc_linux_dev_reset(Scsi_Cmnd *cmd) -{ - int error; - - error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET); - if (error != 0) - printf("aic7xxx_dev_reset returns 0x%x\n", error); - return (error); -} - -/* - * Reset the SCSI bus. - */ -int -ahc_linux_bus_reset(Scsi_Cmnd *cmd) -{ - struct ahc_softc *ahc; - struct ahc_cmd *acmd; - u_long s; - int found; - - ahc = *(struct ahc_softc **)cmd->host->hostdata; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_unlock_irq(&io_request_lock); -#endif - ahc_midlayer_entrypoint_lock(ahc, &s); - found = ahc_reset_channel(ahc, cmd->channel + 'A', - /*initiate reset*/TRUE); - acmd = TAILQ_FIRST(&ahc->platform_data->completeq); - TAILQ_INIT(&ahc->platform_data->completeq); - ahc_midlayer_entrypoint_unlock(ahc, &s); - if (bootverbose) - printf("%s: SCSI bus reset delivered. " - "%d SCBs aborted.\n", ahc_name(ahc), found); - - if (acmd != NULL) { - acmd = ahc_linux_run_complete_queue(ahc, acmd); - if (acmd != NULL) { - ahc_midlayer_entrypoint_lock(ahc, &s); - ahc_schedule_completeq(ahc, acmd); - ahc_midlayer_entrypoint_unlock(ahc, &s); - } - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) - spin_lock_irq(&io_request_lock); -#endif - return SUCCESS; -} - -/* - * Return the disk geometry for the given SCSI device. - */ -int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, - sector_t capacity, int geom[]) -#else -ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) -#endif -{ - int heads; - int sectors; - int cylinders; - int ret; - int extended; - struct ahc_softc *ahc; - u_int channel; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - uint8_t *bh; - - channel = sdev->channel; -#else - u_long capacity; - struct buffer_head *bh; - - capacity = disk->capacity; - channel = disk->device->channel; -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - ahc = *((struct ahc_softc **)sdev->host->hostdata); -#else - ahc = *((struct ahc_softc **)disk->device->host->hostdata); -#endif - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - bh = scsi_bios_ptable(bdev); -#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); -#else - bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); -#endif - - if (bh) { - ret = scsi_partsize(bh, capacity, - &geom[2], &geom[0], &geom[1]); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) - kfree(bh); -#else - brelse(bh); -#endif - if (ret != -1) - return (ret); - } - heads = 64; - sectors = 32; - cylinders = capacity / (heads * sectors); - - if (aic7xxx_extended != 0) - extended = 1; - else if (channel == 0) - extended = (ahc->flags & AHC_EXTENDED_TRANS_A) != 0; - else - extended = (ahc->flags & AHC_EXTENDED_TRANS_B) != 0; - if (extended && cylinders >= 1024) { - heads = 255; - sectors = 63; - cylinders = capacity / (heads * sectors); - } - geom[0] = heads; - geom[1] = sectors; - geom[2] = cylinders; - return (0); -} - -/* - * Free the passed in Scsi_Host memory structures prior to unloading the - * module. - */ -int -ahc_linux_release(struct Scsi_Host * host) -{ - struct ahc_softc *ahc; - u_long l; - - ahc_list_lock(&l); - if (host != NULL) { - - /* - * We should be able to just perform - * the free directly, but check our - * list for extra sanity. - */ - ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); - if (ahc != NULL) { - u_long s; - - ahc_lock(ahc, &s); - ahc_intr_enable(ahc, FALSE); - ahc_unlock(ahc, &s); - ahc_free(ahc); - } - } - ahc_list_unlock(&l); - return (0); -} - void ahc_platform_dump_card_state(struct ahc_softc *ahc) { @@ -5065,9 +5124,3 @@ ahc_platform_dump_card_state(struct ahc_softc *ahc) } } } - -#if defined(MODULE) || LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static Scsi_Host_Template driver_template = AIC7XXX; -Scsi_Host_Template *aic7xxx_driver_template = &driver_template; -#include "scsi_module.c" -#endif diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index bb12fd4289ed..f4befe1fd415 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -18,7 +18,7 @@ * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#107 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#108 $ * * Copyright (c) 2000-2001 Adaptec Inc. * All rights reserved. @@ -55,7 +55,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#107 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm.h#108 $ * */ #ifndef _AIC7XXX_LINUX_H_ @@ -306,7 +306,7 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec) #include <linux/smp.h> #endif -#define AIC7XXX_DRIVER_VERSION "6.2.22" +#define AIC7XXX_DRIVER_VERSION "6.2.23" /**************************** Front End Queues ********************************/ /* diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 1b076d1ff3d1..495367b66a6d 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c @@ -36,7 +36,7 @@ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * - * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#40 $ + * $Id: //depot/aic7xxx/linux/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c#41 $ */ #include "aic7xxx_osm.h" @@ -177,7 +177,7 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) pci_set_drvdata(pdev, ahc); if (aic7xxx_detect_complete) - ahc_linux_register_host(ahc, aic7xxx_driver_template); + ahc_linux_register_host(ahc, &aic7xxx_driver_template); #endif return (0); } |
