summaryrefslogtreecommitdiffstats
path: root/sys/dev/isp
Commit message (Collapse)AuthorAgeFilesLines
* Core version 2.0 rewrite. In this file we replace isp_tdebug withmjacob2000-08-011-118/+104
| | | | | | isp_prt calls. We now use an argument to the ISPCTL_FCLINK_TEST call. We change all IDPRINTF macros to isp_prt calls. We add the isp_prt function here.
* Core version 2.0 cleanup/rewrite. Things get rearranged and changedmjacob2000-08-011-164/+233
| | | | | | | | | | quite a bit so that all of the ports have a similar set of required macros/definitions (and in similar places in the isp_<platform>.h file). Some new macros/functions added- Mailbox Acquire/Relase macros, NANOTIME macros, SNPRINTf and STRNCAT. MemoryBarrier beomes MEMORYBARRIER with much stronger types.
* Remove isp_prtstst (now in case statement in isp.c). Removemjacob2000-08-011-116/+47
| | | | | | | isp2100_fw_statename as an INLINE (now a function in isp.c). Remove isp2100_pdb_statename (unused). Redo all ISP_SCSI_XFER_T as XS_T types. Change all RQUEST_QUEUE_LEN/RESULT_QUEUE_LEN macros to take a parameter. Add isp_print_bytes function.
* Remove isp_tdebug. Change all PRINTF macros to the now commonmjacob2000-08-011-125/+117
| | | | isp_prt logging function.
* Fix typo. Remove isp_tdebug (we'll use ISP_LOGTDEBUG2 in isp->isp_dblevmjacob2000-08-011-6/+3
| | | | as a selector now). Change DFLT_CMD_CNT to a fixed amount for now.
* Add in lengths of SBus or PCI registers.mjacob2000-08-011-0/+3
|
* Rewrite for version 2.0. Some structural changes, but alsomjacob2000-08-011-34/+189
| | | | | a substantial amount of commenting about what each platform specific definitions are supposed to be.
* Part of major rewrite for core version 2.0- clarification ofmjacob2000-08-011-99/+106
| | | | | mdvec structure, removal of printf/CFGPRINTF in place of isp_prt calls. Parameterization of RQUEST_QUEUE_LEN/RESULT_QUEUE_LEN.
* Add in some new IN_XXX and CT_XXXX flags in preparationmjacob2000-07-181-0/+6
| | | | | for the rototilling that !*$)~@!$_@*_(~@$*_(~@$*~@$* Qlogic F/W changes will need.
* If debugging set, zero out an incoming response entrymjacob2000-07-181-1/+5
| | | | | | | when we're done reading it (makes checking things easier). Before calling isp_notify_ack make sure we're at RUNSTATE- elsewise we can be responding to LIPs or SCSI bus resets before we've finished some of the wiring.
* The SERVICING_INTERRUPT isn't quite safe yet.mjacob2000-07-181-0/+4
|
* Add a isp_target_putback_atio- we aren't using CCINCR at this time, somjacob2000-07-181-40/+169
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | we need a function that tells the Qlogic f/w that a target mode command is done, so increase the resource count for that lun. Add in a timeout function to kick the putback again if we fail to do it the first time (we may not have the request queue space for ATIO push). Split the function isp_handle_platform_ctio into two parts so that the timeout function for the ATIO push or isp_handle_platform_ctio can inform CAM that the requested CTIO(s) are now done. Clean up (cough) residual handling. What we need for Fibre Channel is to preserve the at_datalen field from the original incoming ATIO so we can calculate a 'true' residual. Unfortunately, we're not guaranteed to get that back from CAM. We'll *try* to find it hiding in the periph_priv field (layering violation)- but if an ATIO was passed in from user land- forget it. This means that we'll probably get residuals wrong for Fibre Channel commands we're completing with an error. It's too late to 4.1 release to fix this- too bad. Luckily the only device we'd really care about this occurring on is a tape device and they're still so rare as FC attached devices that this can be considered an untested combination anyway. Remove all CCINCR usage (resource autoreplenish). When we've proved to ourself that things are working properly, we can add it back in. Make sure we propage 'suggested' sense data from the incoming ATIO into the created system ATIO- and set sense_len appropriately. Correctly propagate tag values. Fall back to the model of generating (well, the functions in isp_pci.c do the work) multiple CTIOs based upon what we get from XPT. Instead of being able to pair Qlogic generated ATIOs with CAM ATIOs, and then to pair CAM CTIOs with Qlogic CTIOs, we have to take the CTIO passed to us from XPT, and if it implies that we have to generate extra Qlogic CTIOs, so be it. This means that we have to wait until the last CTIO in a sequence we generated completes before calling xpt_done. Executive summary- target mode actually now pretty much works well enough to tell folks about.
* Raise debug level for some messages. Fix botched inversionmjacob2000-07-181-11/+9
| | | | about MBOX_COMMAND_ERROR vs. MBOX_COMMAND_PARAM_ERROR.
* Keep interrupts blocked for all of isp_pci_attach. Redo DMA routinesmjacob2000-07-181-78/+161
| | | | for target mode for cleanliness and accuracy.
* Oops! If we're deciding a command is now really dead, make *darned*mjacob2000-07-051-0/+9
| | | | | | sure that it really is by issuing a ISPCTL_ABORT_CMD just on the off chance the f/w will start it up again and, ha ha, start using the DMA resources we gave it but are now taking away.
* Clean up ISPCTL_ABORT_CMD function to not be too chatty if it succeeds,mjacob2000-07-051-7/+14
| | | | | or even if it fails with INVALID_PARM (which just means that the handle doesn't refer to an active commane).
* Remove obsolete isp_dogactive tag.mjacob2000-07-041-1/+1
|
* Fix completely stupid and idiotiuc sprintfs in isp_inline.h withmjacob2000-07-041-36/+19
| | | | with the STRNCAT function.
* Add in config_hook for catching when interrupts are safe- this allowsmjacob2000-07-041-72/+91
| | | | | | us to not the ints are ok and also to (re)ENABLE isp interrupts. Remove all splcam()/splx() invocates and replace them with ISP_LOCK/ISP_UNLOCK macros.
* Add in isp_lock/isp_unlock inlines. Add in an islocked/intsok flagmjacob2000-07-041-9/+82
| | | | | | | | | to isp_osinfo substructure (all in prep for SMP). Define MBOX_WAIT_COMPLETE and MBOX_NOTIFY_COMPLETE macros so that we can now (temp) use tsleep to wait for mailbox completion. Requires us to guess whether we're servicing an interrupt or not- will use intr_nesting_level. Add local strncat function.
* Change delay loop in new isp_mboxcmd to the use of the new MBOX_WAIT_COMPLETEmjacob2000-07-041-7/+2
| | | | | macro. Change notification of completion of a mailbox command in isp_intr to MBOX_NOTIFY_COMPLETE macro.
* Change startup locking. Use new isp_handle_index functionmjacob2000-07-041-20/+16
| | | | for indexing off of handles to get dma maps.
* Fix usage of DELAY (SYS_DELAY is the platform independent localmjacob2000-06-271-469/+382
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | define). Fix stupidity wrt checking whether we've gone to LOOP_PDB_RCVD loopstate- it's okay to be greater than this state. D'oh! Protect calls to isp_pdb_sync and isp_fclink_state with IS_FC macros. Completely redo mailbox command routine (in preparation to make this possibly wait rather than poll for completion). Make a major attempt to solve the 'lost interrupt' problem 1. Problem The Qlogic cards would appear to 'lose' interrupts, i.e., a legitimate regular SCSI command placed on the request queue would never complete and the watchdog routine in the driver would eventually wakeup and catch it. This would typically only happen on Alphas, although a couple folks with 700MHz Intel platforms have also seen this. For a long time I thought it was a foulup with f/w negotiations of SYNC and/or WIDE as it always seemed to happen right after the platform it was running on had done a SET TARGET PARAMETERS mailbox command to (re)enable sync && wide (after initially forcing ASYNC/NARROW at startup). However, occasionally, the same thing would also occur for the Fibre Channel cards as well (which, ahem, have no SET TARGET PARAMETERS for transfer mode). After finally putting in a better set of watchdog routines for the platforms for this driver, it seemed to be the case that the command in question (usually a READ CAPACITY) just had up and died- the watchdog routine would catch it after ~10 seconds. For some platforms (NetBSD/OpenBSD)- an ABORT COMMAND mailbox command was sent (which would always fail- indicating that the f/w denied knowledge of this command, i.e., the f/w thought it was a done command). In any case, retrying the command worked. But this whole problem needed to be really fixed. 2. A False Step That Went in The Right Direction The mailbox code was completely rewritten to no longer try and grab the mailbox semaphore register and to try and 'by hand' complete async fast posting completions. It was also rewritten to now have separate in && out bitpatterns for registers to load to start and retrieve to complete. This means that isp_intr now handles mailbox completions. This substantially simplifies the mailbox handling code, and carries things 90% toward getting this to be a non-polled routine for this driver. This did not solve the problem, though. 3. Register Debouncing I saw some comments in some errata sheets and some notes in a Qlogic produced Linux driver (for the Qlogic 2100) that seemed to indicate that debouncing of reads of the mailbox registers might be needed, so I added this. This did not affect the problem. In fact, it made the problem worse for non-2100 cards. 5. Interrupt masking/unmasking The driver *used* to do a substantial amount of masking/unmasking of the interrupt control register. This was done to make sure that the core common code could just assume it would never get pre-empted. This apparently substantially contributed to the lost interrupt problem. The rewrite of the ICR (Interrupt Control Register), which is a separate register from the ISR (Interrupt Status Register) should not have caused any change to interrupt assertions pending. The manual does not state that it will, and the register layout seems to imply that the ICR is just an active route gate. We only enable PCI Interrupts and RISC Interrupts- this should mean that when the f/w asserts a RISC interrupt and (and the ICR allows RISC Interrupts) and we have PCI Interrupts enabled, we should get a PCI interrupt. Apparently this is a latch- not a signal route. Removing this got rid of *most* but not all, lost interrupts. 5. Watchdog Smartening I made sure that the watchdog routine would catch cases where the Qlogic's ISR showed an interrupt assertion. The watchdog routine now calls the interrupt service routine if it sees this. Some additional internal state flags were added so that the watchdog routine could then know whether the command it was in the middle of burying (because we had time it out) was in fact completed by the interrupt service routine. 6. Occasional Constipation Of Commands.. In running some very strenous high IOPs tests (generating about 11000 interrupts/second across one Qlogic 1040, one Qlogic 1080 and one Qlogic 2200 on an Alpha PC164), I found that I would get occasional but regular 'watchdog timeouts' on both the 1080 and the 2100 cards. This is under FreeBSD, and the watchdog timeout routine just marks the command in error and retries it. Invariably, right after this 'watchdog timeout' error, I'd get a command completion for the command that I had thought timed out. That is, I'd get a command completion, but the handle returned by the firmware mapped to no current command. The frequency of this problem is low under such a load- it would usually take an 30 minutes per 'lost' interrupt. I doubled the timeout for commands to see if it just was an edge case of waiting too short a period. This has no effect. I gathered and printed out microtimes for the watchdog completed command and the completion that couldn't find a command- it was always the case that the order of occurrence was "timeout, completion" separated by a time on the order of 100 to 150 ms. This caused me to consider 'firmware constipation' as to be a possible culprit. That is, resubmission of a command to the device that had suffered a watchdog timeout seemed to cause the presumed dead command to show back up. I added code in the watchdog routine that, when first entered for the command, marks the command with a flag, reissues a local timeout call for one second later, but also then issues a MARKER Request Queue entry to the Qlogic f/w. A MARKER entry is used typically after a Bus Reset to cause the f/w to get synchronized with respect to either a Bus, a Nexus or a Target. Since I've added this code, I always now see the occasional watchdog timeout, but the command that was about to be terminated always now seems to be completed after the MARKER entry is issued (and before the timeout extension fires, which would come back and *really* terminate the command).
* Add in the enabling of interrupts (to isp_attach). Clean up a bustedmjacob2000-06-271-34/+93
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | comment. Check against firmware state- not loop state when enabling target mode. Other changes have to do with no longer enabling/disabling interrupts at will. Rearchitect command watchdog timeouts- First of all, set the timeout period for a command that has a timeout (in isp_action) to the period of time requested *plus* two seconds. We don't want the Qlogic firmware and the host system to race each other to report a dead command (the watchdog is there to catch dead and/or broken firmware). Next, make sure that the command being watched isn't done yet. If it's not done yet, check for INT_PENDING and call isp_intr- if that said it serviced an interrupt, check to see whether the command is now done (this is what the "IN WATCHDOG" private flag is for- if isp_intr completes the command, it won't call xpt_done on it because isp_watchdog is still looking at the command). If no interrupt was pending, or the command wasn't completed, check to see if we've set the private 'grace period' flag. If so, the command really *is* dead, so report it as dead and complete it with a CAM_CMD_TIMEOUT value. If the grace period flag wasn't set, set it and issue a SYNCHRONIZE_ALL Marker Request Queue entry and re-set the timeout for one second from now (see Revision 1.45 isp.c notes for more on this) to give the firmware a final chance to complete this command.
* Clean up private storage so that we can use the spriv_field0 tomjacob2000-06-271-12/+33
| | | | | | | | | store a bitmask of whether we've set a value into ccb->ccb_h.status, whether we're in the watchdog routine for this command now, whether we've set a grace period for this command and whether this command is actually done. See comments of rev 1.45 of isp.c for more complete information.
* Add 8 bits of volatile mailbox busy mask- this will be the bitmask ofmjacob2000-06-271-3/+5
| | | | | | | | output mailbox values we want to get back out of the chip once a mailbox command is done. Add storage for the maximum number of output mailbox registers to the softc. Roll minor version number.
* Add mailbox bitmask macros (numbers of available mailbox registersmjacob2000-06-271-1/+9
| | | | | based upon Qlogic chip type). Define maximum mailboxes. Add INT_PENDING_MASK macro. Change mailbox offset macro name.
* Add an isp_handle_index function- this is prepatory to loading more intomjacob2000-06-271-3/+15
| | | | | | | the handle (i.e., generation number), so we will now need a function that will take a handle and return a flat index [ 0 .. maxhandles-1 ] for auxillary routines that need an index to get at buddy store values (like dma maps or xflist pointers).
* Clean up firmware load issues and remove darn near all config options.mjacob2000-06-181-95/+43
| | | | | | | | | | | | | | | | | | Force alphas to prefer mem mapping as the default. Basically, we have a pointer to a function which we can call which will return us a pointer to firmware for the card we have. We call this function (if it's non-NULL) with the address of our mdvec f/w pointer. The way this works is that if ispfw (as a module or a static) is loaded, it initializes the pointer in isp_pci, so we can call into to it to fetch a pointer to a f/w set. If ispfw is MOD_UNLOADed, it's retained a pointer to our mdvec f/w pointers, which then get zeroed out so we don't have any references to data that's now gone from kernel memory. Removing the f/w saves ~360KBytes. Alas, there is no autounload mechanism that works for is here.
* Removing this bulky one large f/w file. This f/w is now in dev/ispfw.mjacob2000-06-181-36137/+0
|
* Once we have firmware running (if isp_reset) and this is the first timemjacob2000-06-181-34/+74
| | | | | | | | | | | | | | | | | | | | through, establish what our LUN width is. Unfortunately, we can't ask the f/w. If we loaded the f/w, we'll now assume we have expanded LUNs (SCCLUN for fibre channel, just plain 32 LUN for SCSI). If we didn't load firmware, assume 8 LUNs for SCSI and 1 LUN for Fibre Channel. We have to assume only one LUN for Fibre Channel because the LUN setting in Request Queue entries is in different places whether we have SCCLUN firmware or not, so the only LUN guaranteed to work for both is LUN 0. Clean up the rest of isp.c so that ISP2100_SCCLUN defines aren't used- instead use run time determinants based upon isp->isp_maxluns. After starting firmware, delay 500us to give it a chance to get rolling. Fix the interrupt service routine to check for both isr && sema being zero before thinking this was a spurious interrupt. Following the manuals, allow for both Mailbox as well as Queue Reponse type interrupts for regular SCSI.
* Remove all ISP2100_SCCLUN define protected code and replace it withmjacob2000-06-181-23/+12
| | | | runtime checks.
* Remove all ISP2100_SCCLUN define based code and replace it with runtimemjacob2000-06-181-27/+27
| | | | | | comparisons against the tag isp_maxluns- if > 16, we're SCCLUN based. On initial regular SCSI startup, disable auto-disconnect.
* Roll platform minor number. Force definition of SCSI_ISP_FABRICmjacob2000-06-181-8/+6
| | | | | | (we always support fabric now). Remove SCCLUN definition (we always support SCCLUN now, if we load the f/w). Add typedef definition of an external firmware fetch function.
* Roll core minor version. Set ISP_MAX_LUNS to be off of new isp_maxlunsmjacob2000-06-181-11/+4
| | | | tag in softc.
* add "disable autodisconnect" flagsmjacob2000-06-181-0/+1
|
* cleanup i_int_X vs. uint_X definitionsmjacob2000-06-181-16/+16
|
* add MBOX_GET_RESOURCE_COUNT commandmjacob2000-06-181-0/+1
|
* Fix breakage to target mode support.mjacob2000-06-121-14/+25
| | | | | | | | | | | | | | | | | | | | | | | What we'd like to know is whether or not we have a listener upstream that really hasn't configured yet. If we do, then we can give a more sensible reply here. If not, then we can reject this out of hand. Choices for what to send were Not Ready, Unit Not Self-Configured Yet (0x2,0x3e,0x00) for the former and Illegal Request, Logical Unit Not Supported (0x5,0x25,0x00) for the latter. We used to decide whether there was at least one listener based upon whether the black hole driver was configured. However, recent config(8) changes have made this hard to do at this time. Actually, we didn't use the above quite yet, but were sure considering it.
* Fix some breakage about how we build WWNs. Do some other fabric relatedmjacob2000-05-091-136/+247
| | | | | | | | | | | | changes: consider a new PDB entry different if Class 3 service parameter roles change (!!!). Do some checking as we're getting a port database that traps whether things change while we're doing so. Handle N-port and F-ports correctly. Fix the fabric login loop to retain a login/binding if things haven't changed (I mean, why logout a device only to log it back in). No longer accept, after fabric logins, garbage if we can't get a PDB entry that matches the device we've just logged into- if it doesn't, log it out as it is very unlikely to still be what we thought it was. Get rid of some of the debounce loops because we could get stuck there.
* roll platform minormjacob2000-05-091-1/+1
|
* Roll core minor version. Change our 'fabdev' tag to 'loggedin'.mjacob2000-05-091-6/+6
|
* Add in a watchdog routine to catch cases where we've dropped the command.mjacob2000-05-091-2/+32
| | | | | | | Apparently the f/w has finished the command, but somehow an interrupt is being lost. So, we just plain wedge when booting alphas. This is a general routine we've needed for a while.
* The storage for WWN from NVRAM is actually the PORT WWN, not the NODE WWN.mjacob2000-05-091-1/+12
|
* Conrrect a macro with parenthesis.mjacob2000-05-091-1/+1
|
* Now that we fixed the isp_sendmarker botch, we can now do initial busmjacob2000-04-211-4/+1
| | | | | resets for ULTRA2/ULTRA3 cards again (which were turned off really because of a botch for dual bus configurations).
* Roll minor version. Increase size (and add defines for) topology storage.mjacob2000-04-211-2/+9
|
* Some minor tweaklets.mjacob2000-04-213-21/+44
|
* Add in the now required malloc.h include. I guess somebodymjacob2000-04-211-0/+1
| | | | was busy hackin' w/o checking kernel compiles.
* Pick up topology more sanely at f/w startup. Change the restrictions ofmjacob2000-04-211-22/+34
| | | | | | | where we can have targets (based on topology). Much more importantly, make sure all mods to isp_sendmarker or |= so we don't lose the marking of a bus that needs to have a marker sent for it.
OpenPOWER on IntegriCloud