* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGES.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#134 $
- *
- * $FreeBSD$
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#155 $
*/
#ifdef __linux__
#include <dev/aic7xxx/aicasm/aicasm_insformat.h>
#endif
-/****************************** Softc Data ************************************/
-struct ahc_softc_tailq ahc_tailq = TAILQ_HEAD_INITIALIZER(ahc_tailq);
-
/***************************** Lookup Tables **********************************/
char *ahc_chip_names[] =
{
ahc_outb(ahc, SEQ_FLAGS2,
ahc_inb(ahc, SEQ_FLAGS2) & ~SCB_DMA);
}
+
+ /*
+ * Clear any pending sequencer interrupt. It is no
+ * longer relevant since we're resetting the Program
+ * Counter.
+ */
+ ahc_outb(ahc, CLRINT, CLRSEQINT);
+
ahc_outb(ahc, MWI_RESIDUAL, 0);
ahc_outb(ahc, SEQCTL, ahc->seqctl);
ahc_outb(ahc, SEQADDR0, 0);
ahc_outb(ahc, SEQADDR1, 0);
+
ahc_unpause(ahc);
}
scb_index);
}
#endif
- /*
- * Force a renegotiation with this target just in
- * case the cable was pulled and will later be
- * re-attached. The target may forget its negotiation
- * settings with us should it attempt to reselect
- * during the interruption. The target will not issue
- * a unit attention in this case, so we must always
- * renegotiate.
- */
ahc_scb_devinfo(ahc, &devinfo, scb);
- ahc_force_renegotiation(ahc, &devinfo);
ahc_set_transaction_status(scb, CAM_SEL_TIMEOUT);
ahc_freeze_devq(ahc, scb);
+
+ /*
+ * Cancel any pending transactions on the device
+ * now that it seems to be missing. This will
+ * also revert us to async/narrow transfers until
+ * we can renegotiate with the device.
+ */
+ ahc_handle_devreset(ahc, &devinfo,
+ CAM_SEL_TIMEOUT,
+ "Selection Timeout",
+ /*verbose_level*/1);
}
ahc_outb(ahc, CLRINT, CLRSCSIINT);
ahc_restart(ahc);
/*period*/0, /*offset*/0, /*ppr_options*/0,
AHC_TRANS_CUR, /*paused*/TRUE);
- ahc_send_async(ahc, devinfo->channel, devinfo->target,
- CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
+ if (status != CAM_SEL_TIMEOUT)
+ ahc_send_async(ahc, devinfo->channel, devinfo->target,
+ CAM_LUN_WILDCARD, AC_SENT_BDR, NULL);
if (message != NULL
&& (verbose_level <= bootverbose))
return (0);
}
-void
-ahc_softc_insert(struct ahc_softc *ahc)
-{
- struct ahc_softc *list_ahc;
-
-#if AHC_PCI_CONFIG > 0
- /*
- * Second Function PCI devices need to inherit some
- * settings from function 0.
- */
- if ((ahc->chip & AHC_BUS_MASK) == AHC_PCI
- && (ahc->features & AHC_MULTI_FUNC) != 0) {
- TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
- ahc_dev_softc_t list_pci;
- ahc_dev_softc_t pci;
-
- list_pci = list_ahc->dev_softc;
- pci = ahc->dev_softc;
- if (ahc_get_pci_slot(list_pci) == ahc_get_pci_slot(pci)
- && ahc_get_pci_bus(list_pci) == ahc_get_pci_bus(pci)) {
- struct ahc_softc *master;
- struct ahc_softc *slave;
-
- if (ahc_get_pci_function(list_pci) == 0) {
- master = list_ahc;
- slave = ahc;
- } else {
- master = ahc;
- slave = list_ahc;
- }
- slave->flags &= ~AHC_BIOS_ENABLED;
- slave->flags |=
- master->flags & AHC_BIOS_ENABLED;
- slave->flags &= ~AHC_PRIMARY_CHANNEL;
- slave->flags |=
- master->flags & AHC_PRIMARY_CHANNEL;
- break;
- }
- }
- }
-#endif
-
- /*
- * Insertion sort into our list of softcs.
- */
- list_ahc = TAILQ_FIRST(&ahc_tailq);
- while (list_ahc != NULL
- && ahc_softc_comp(ahc, list_ahc) <= 0)
- list_ahc = TAILQ_NEXT(list_ahc, links);
- if (list_ahc != NULL)
- TAILQ_INSERT_BEFORE(list_ahc, ahc, links);
- else
- TAILQ_INSERT_TAIL(&ahc_tailq, ahc, links);
- ahc->init_level++;
-}
-
void
ahc_set_unit(struct ahc_softc *ahc, int unit)
{
* to disturb the integrity of the bus.
*/
ahc_pause(ahc);
- if ((ahc_inb(ahc, HCNTRL) & CHIPRST) != 0) {
- /*
- * The chip has not been initialized since
- * PCI/EISA/VLB bus reset. Don't trust
- * "left over BIOS data".
- */
- ahc->flags |= AHC_NO_BIOS_INIT;
- }
sxfrctl1_b = 0;
if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7770) {
u_int sblkctl;
ahc->flags |= AHC_ALL_INTERRUPTS;
paused = FALSE;
do {
- if (paused)
+ if (paused) {
ahc_unpause(ahc);
+ /*
+ * Give the sequencer some time to service
+ * any active selections.
+ */
+ ahc_delay(500);
+ }
ahc_intr(ahc);
ahc_pause(ahc);
paused = TRUE;
ahc_outb(ahc, SCSISEQ, ahc_inb(ahc, SCSISEQ) & ~ENSELO);
- ahc_clear_critical_section(ahc);
intstat = ahc_inb(ahc, INTSTAT);
+ if ((intstat & INT_PEND) == 0) {
+ ahc_clear_critical_section(ahc);
+ intstat = ahc_inb(ahc, INTSTAT);
+ }
} while (--maxloops
&& (intstat != 0xFF || (ahc->features & AHC_REMOVABLE) == 0)
&& ((intstat & INT_PEND) != 0