From owner-cvs-all@FreeBSD.ORG Wed Feb 4 08:39:06 2004 Return-Path: Delivered-To: cvs-all@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 27E8B16A4CE; Wed, 4 Feb 2004 08:39:06 -0800 (PST) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2A31E43D5D; Wed, 4 Feb 2004 08:38:39 -0800 (PST) (envelope-from gibbs@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.10/8.12.10) with ESMTP id i14Gcc0B087813; Wed, 4 Feb 2004 08:38:39 -0800 (PST) (envelope-from gibbs@repoman.freebsd.org) Received: (from gibbs@localhost) by repoman.freebsd.org (8.12.10/8.12.10/Submit) id i14GccXu087812; Wed, 4 Feb 2004 08:38:38 -0800 (PST) (envelope-from gibbs) Message-Id: <200402041638.i14GccXu087812@repoman.freebsd.org> From: "Justin T. Gibbs" Date: Wed, 4 Feb 2004 08:38:38 -0800 (PST) To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org X-FreeBSD-CVS-Branch: HEAD Subject: cvs commit: src/sys/dev/aic7xxx aic79xx.c aic79xx.h aic79xx.reg aic79xx.seq aic79xx_inline.h aic79xx_pci.c X-BeenThere: cvs-all@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: CVS commit messages for the entire tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Feb 2004 16:39:06 -0000 gibbs 2004/02/04 08:38:38 PST FreeBSD src repository Modified files: sys/dev/aic7xxx aic79xx.c aic79xx.h aic79xx.reg aic79xx.seq aic79xx_inline.h aic79xx_pci.c Log: aic79xx.c: aic79xx.seq: Convert the COMPLETE_DMA_SCB list to an "stailq". This allows us to safely keep the SCB that is currently being DMA'ed back the host on the head of the list while processing completions off of the bus. The newly completed SCBs are appended to the tail of the queue. In the past, we just dequeued the SCB that was in flight from the list, but this could result in a lost completion should the host perform certain types of error recovery that must cancel all in-flight SCB DMA operations. Switch from using a 16bit completion entry, holding just the tag and the completion valid bit, to a 64bit completion entry that also contains a "status packet valid" indicator. This solves two problems: o The SCB DMA engine on at least Rev B. silicon does not properly deal with a PCI disconnect that occurs at a non-64bit aligned offset in the chips "source buffer". When the transfer is resumed, the DMA engine continues at the correct offset, but may wrap to the head of the buffer causing duplicate completions to be reported to the host. By using a completion buffer in host memory that is 64bit aligned and using 64bit completion entries, such disconnects should only occur at aligned addresses. This assumes that the host bridge will only disconnect on cache-line boundaries and that cache-lines are multpiles of 64bits. o By embedding the status information in the completion entry we can avoid an extra memory reference to the HSCB for commands that complete without error. Use the comparison of a "host freeze count" and a "sequencer freeze count" to allow the host to process most SCBs that complete with non-zero status without having to clear critical sections. Instead the host can just pause the sequencer, performs any necessary cleanup in the waiting for selection list, increments its freeze count on the controller, and unpauses. This is only possible because the sequencer defers completions of SCBs with bad status until after all pending selections have completed. The sequencer then avoids referencing any data structures the host may touch during completion of the SCB until the freeze counts match. aic79xx.c: Change the strategy for allocating our sentinal HSCB for the QINFIFO. In the past, this allocation was tacked onto the QOUTFIFO allocation. Now that the qoutfifo has grown to accomodate larger completion entries, the old approach will result in a 64byte allocation that costs an extra page of coherent memory. We now do this extra allocation via ahd_alloc_scbs() where the "unused space" can be used to allocate "normal" HSCBs. In our packetized busfree handler, use the ENSELO bit to differentiate between packetized and non-packetized unexpected busfree events that occur just after selection, but before the sequencer has had the oportunity to service the selection. When cleaning out the waiting for selection list, use the SCSI mode instead of the command channel mode. The SCB pointer in the command channel mode may be referenced by the SCB dma engine even while the sequencer is paused, whereas the SCSI mode SCB pointer is only accessed by the sequencer. Print the "complete on qfreeze" sequencer SCB completion list in ahd_dump_card_state(). This list holds all SCB completions that are deferred until a pending select-out qfreeze event has taken effect. aic79xx.h: Add definitions and structures to handle the new SCB completion scheme. Add a controller flag that indicates if the controller is in HostRAID mode. aic79xx.reg: Remove macros used for toggling from one data fifo mode to the other. They have not been in use for some time. Add scratch ram fields for our new qfreeze count scheme, converting the complete dma list into an "stailq", and providing for the "complete on qfreeze" SCB completion list. Some other fields were moved to retain proper field alignment (alignment >= field size in bytes). aic79xx.seq: Add code to our idle loop to: o Process deferred completions once a qfreeze event has taken full effect. o Thaw the queue once the sequencer and host qfreeze counts match. Generate 64bit completion entries passing the SCB_SGPTR field as the "good status" indicator. The first bit in this field is only set if we have a valid status packet to send to the host. Convert the COMPLETE_DMA_SCB list to an "stailq". When using "setjmp" to register an idle loop handler, do not combine the "ret" with the block move to pop the stack address in the same instruction. At least on the A, this results in a return to the setjmp caller, not to the new address at the top of the stack. Since we want the latter (we want the newly registered handler to only be invoked from the idle loop), we must use a separate ret instruction. Add a few missing critical sections. Close a race condition that can occur on Rev A. silicon. If both FIFOs happen to be allocated before the sequencer has a chance to service the FIFO that was allocated first, we must take special care to service the FIFO that is not active on the SCSI bus first. This guarantees that a FIFO will be freed to handle any snapshot requests for the FIFO that is still on the bus. Chosing the incorrect FIFO will result in deadlock. Update comments. aic79xx_inline.h Correct the offset calculation for the syncing of our qoutfifo. Update ahd_check_cmdcmpltqueues() for the larger completion entries. aic79xx_pci.c: Attach to HostRAID controllers by default. In the future I may add a sysctl to modify the behavior, but since FreeBSD does not have any HostRAID drivers, failing to attach just results in more email and bug reports for the author. MFC After: 1week Revision Changes Path 1.28 +119 -63 src/sys/dev/aic7xxx/aic79xx.c 1.18 +26 -9 src/sys/dev/aic7xxx/aic79xx.h 1.16 +37 -20 src/sys/dev/aic7xxx/aic79xx.reg 1.15 +115 -32 src/sys/dev/aic7xxx/aic79xx.seq 1.14 +7 -6 src/sys/dev/aic7xxx/aic79xx_inline.h 1.18 +23 -5 src/sys/dev/aic7xxx/aic79xx_pci.c