[RFC][PATCH] Forward port of aic7xxx driver to 2.5.44 [2/3]

From: SL Baur (steve@kbuxd.necst.nec.co.jp)
Date: Thu Oct 24 2002 - 21:15:38 EST


===== drivers/scsi/aic7xxx/aic7xxx_core.c 1.10 vs edited =====
--- 1.10/drivers/scsi/aic7xxx/aic7xxx_core.c Mon Oct 7 23:39:54 2002
+++ edited/drivers/scsi/aic7xxx/aic7xxx_core.c Wed Oct 23 16:49:30 2002
@@ -37,9 +37,9 @@
  * 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#50 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.c#69 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.61 2000/11/13 03:35:43 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.c,v 1.41.2.22 2002/04/29 19:36:26 gibbs Exp $
  */
 
 #include "aic7xxx_osm.h"
@@ -244,10 +244,15 @@
 
         ahc_pause(ahc);
 
+ /* No more pending messages. */
+ ahc_clear_msg_state(ahc);
+
         ahc_outb(ahc, SCSISIGO, 0); /* De-assert BSY */
         ahc_outb(ahc, MSG_OUT, MSG_NOOP); /* No message to send */
         ahc_outb(ahc, SXFRCTL1, ahc_inb(ahc, SXFRCTL1) & ~BITBUCKET);
         ahc_outb(ahc, LASTPHASE, P_BUSFREE);
+ ahc_outb(ahc, SAVED_SCSIID, 0xFF);
+ ahc_outb(ahc, SAVED_LUN, 0xFF);
 
         /*
          * Ensure that the sequencer's idea of TQINPOS
@@ -327,7 +332,7 @@
                  * Save off the residual
                  * if there is one.
                  */
- ahc_update_residual(scb);
+ ahc_update_residual(ahc, scb);
                 ahc_done(ahc, scb);
         }
 }
@@ -488,7 +493,7 @@
                         /*
                          * Save off the residual if there is one.
                          */
- ahc_update_residual(scb);
+ ahc_update_residual(ahc, scb);
 #ifdef AHC_DEBUG
                         if (ahc_debug & AHC_SHOWSENSE) {
                                 ahc_print_path(ahc, scb);
@@ -810,7 +815,12 @@
                  * target does a command complete.
                  */
                 ahc_freeze_devq(ahc, scb);
- ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+ if ((scb->flags & SCB_SENSE) == 0) {
+ ahc_set_transaction_status(scb, CAM_DATA_RUN_ERR);
+ } else {
+ scb->flags &= ~SCB_SENSE;
+ ahc_set_transaction_status(scb, CAM_AUTOSENSE_FAIL);
+ }
                 ahc_freeze_scb(scb);
 
                 if ((ahc->features & AHC_ULTRA2) != 0) {
@@ -1285,13 +1295,19 @@
                                 if (lastphase == ahc_phase_table[i].phase)
                                         break;
                         }
+ /*
+ * Renegotiate with this device at the
+ * next oportunity just in case this busfree
+ * is due to a negotiation mismatch with the
+ * device.
+ */
+ ahc_force_renegotiation(ahc);
                         printf("Unexpected busfree %s\n"
                                "SEQADDR == 0x%x\n",
                                ahc_phase_table[i].phasemsg,
                                ahc_inb(ahc, SEQADDR0)
                                 | (ahc_inb(ahc, SEQADDR1) << 8));
                 }
- ahc_clear_msg_state(ahc);
                 ahc_outb(ahc, CLRINT, CLRSCSIINT);
                 ahc_restart(ahc);
         } else {
@@ -1388,9 +1404,8 @@
                         stepping = TRUE;
                 }
                 ahc_outb(ahc, HCNTRL, ahc->unpause);
- do {
+ while (!ahc_is_paused(ahc))
                         ahc_delay(200);
- } while (!ahc_is_paused(ahc));
         }
         if (stepping) {
                 ahc_outb(ahc, SIMODE0, simode0);
@@ -1409,11 +1424,18 @@
         ahc_outb(ahc, CLRSINT1, CLRSELTIMEO|CLRATNO|CLRSCSIRSTI
                                 |CLRBUSFREE|CLRSCSIPERR|CLRPHASECHG|
                                 CLRREQINIT);
+ ahc_flush_device_writes(ahc);
         ahc_outb(ahc, CLRSINT0, CLRSELDO|CLRSELDI|CLRSELINGO);
+ ahc_flush_device_writes(ahc);
         ahc_outb(ahc, CLRINT, CLRSCSIINT);
+ ahc_flush_device_writes(ahc);
 }
 
 /**************************** Debugging Routines ******************************/
+#ifdef AHC_DEBUG
+int ahc_debug = AHC_DEBUG;
+#endif
+
 void
 ahc_print_scb(struct scb *scb)
 {
@@ -1482,7 +1504,7 @@
                 memcpy(tstate, master_tstate, sizeof(*tstate));
                 memset(tstate->enabled_luns, 0, sizeof(tstate->enabled_luns));
                 tstate->ultraenb = 0;
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < AHC_NUM_TARGETS; i++) {
                         memset(&tstate->transinfo[i].curr, 0,
                               sizeof(tstate->transinfo[i].curr));
                         memset(&tstate->transinfo[i].goal, 0,
@@ -1531,7 +1553,8 @@
 struct ahc_syncrate *
 ahc_devlimited_syncrate(struct ahc_softc *ahc,
                         struct ahc_initiator_tinfo *tinfo,
- u_int *period, u_int *ppr_options, role_t role) {
+ u_int *period, u_int *ppr_options, role_t role)
+{
         struct ahc_transinfo *transinfo;
         u_int maxsync;
 
@@ -2513,9 +2536,13 @@
                 } else
                         ahc->msgin_index++;
 
- /* Ack the byte */
- ahc_outb(ahc, CLRSINT1, CLRREQINIT);
- ahc_inb(ahc, SCSIDATL);
+ if (message_done == MSGLOOP_TERMINATED) {
+ end_session = TRUE;
+ } else {
+ /* Ack the byte */
+ ahc_outb(ahc, CLRSINT1, CLRREQINIT);
+ ahc_inb(ahc, SCSIDATL);
+ }
                 break;
         }
         case MSG_TYPE_TARGET_MSGIN:
@@ -2726,6 +2753,17 @@
          * extended message type.
          */
         switch (ahc->msgin_buf[0]) {
+ case MSG_DISCONNECT:
+ case MSG_SAVEDATAPOINTER:
+ case MSG_CMDCOMPLETE:
+ case MSG_RESTOREPOINTERS:
+ case MSG_IGN_WIDE_RESIDUE:
+ /*
+ * End our message loop as these are messages
+ * the sequencer handles on its own.
+ */
+ done = MSGLOOP_TERMINATED;
+ break;
         case MSG_MESSAGE_REJECT:
                 response = ahc_handle_msg_reject(ahc, devinfo);
                 /* FALLTHROUGH */
@@ -3515,6 +3553,15 @@
         ahc = device_get_softc((device_t)platform_arg);
 #endif
         memset(ahc, 0, sizeof(*ahc));
+ ahc->seep_config = malloc(sizeof(*ahc->seep_config),
+ M_DEVBUF, M_NOWAIT);
+ if (ahc->seep_config == NULL) {
+#ifndef __FreeBSD__
+ free(ahc, M_DEVBUF);
+#endif
+ free(name, M_DEVBUF);
+ return (NULL);
+ }
         LIST_INIT(&ahc->pending_scbs);
         /* We don't know our unit number until the OSM sets it */
         ahc->name = name;
@@ -3527,7 +3574,7 @@
         ahc->bugs = AHC_BUGNONE;
         ahc->flags = AHC_FNONE;
 
- for (i = 0; i < 16; i++)
+ for (i = 0; i < AHC_NUM_TARGETS; i++)
                 TAILQ_INIT(&ahc->untagged_queues[i]);
         if (ahc_platform_alloc(ahc, platform_arg) != 0) {
                 ahc_free(ahc);
@@ -3614,6 +3661,22 @@
         ahc->init_level++;
 }
 
+/*
+ * Verify that the passed in softc pointer is for a
+ * controller that is still configured.
+ */
+struct ahc_softc *
+ahc_find_softc(struct ahc_softc *ahc)
+{
+ struct ahc_softc *list_ahc;
+
+ TAILQ_FOREACH(list_ahc, &ahc_tailq, links) {
+ if (list_ahc == ahc)
+ return (ahc);
+ }
+ return (NULL);
+}
+
 void
 ahc_set_unit(struct ahc_softc *ahc, int unit)
 {
@@ -3694,6 +3757,8 @@
 #endif
         if (ahc->name != NULL)
                 free(ahc->name, M_DEVBUF);
+ if (ahc->seep_config != NULL)
+ free(ahc->seep_config, M_DEVBUF);
 #ifndef __FreeBSD__
         free(ahc, M_DEVBUF);
 #endif
@@ -3714,7 +3779,7 @@
         ahc_outb(ahc, SXFRCTL0, 0);
         ahc_outb(ahc, DSPCISTATUS, 0);
 
- for (i = TARG_SCSIRATE; i < HA_274_BIOSCTRL; i++)
+ for (i = TARG_SCSIRATE; i < SCSICONF; i++)
                 ahc_outb(ahc, i, 0);
 }
 
@@ -3753,7 +3818,10 @@
         ahc_outb(ahc, HCNTRL, CHIPRST | ahc->pause);
 
         /*
- * Ensure that the reset has finished
+ * Ensure that the reset has finished. We delay 1000us
+ * prior to reading the register to make sure the chip
+ * has sufficiently completed its reset to handle register
+ * accesses.
          */
         wait = 1000;
         do {
@@ -3846,11 +3914,26 @@
 static void
 ahc_build_free_scb_list(struct ahc_softc *ahc)
 {
+ int scbsize;
         int i;
 
+ scbsize = 32;
+ if ((ahc->flags & AHC_LSCBS_ENABLED) != 0)
+ scbsize = 64;
+
         for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+ int j;
+
                 ahc_outb(ahc, SCBPTR, i);
 
+ /*
+ * Touch all SCB bytes to avoid parity errors
+ * should one of our debugging routines read
+ * an otherwise uninitiatlized byte.
+ */
+ for (j = 0; j < scbsize; j++)
+ ahc_outb(ahc, SCB_BASE+j, 0xFF);
+
                 /* Clear the control byte. */
                 ahc_outb(ahc, SCB_CONTROL, 0);
 
@@ -3860,17 +3943,15 @@
                 else
                         ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
 
- /* Make the tag number invalid */
+ /* Make the tag number, SCSIID, and lun invalid */
                 ahc_outb(ahc, SCB_TAG, SCB_LIST_NULL);
+ ahc_outb(ahc, SCB_SCSIID, 0xFF);
+ ahc_outb(ahc, SCB_LUN, 0xFF);
         }
 
         /* Make sure that the last SCB terminates the free list */
         ahc_outb(ahc, SCBPTR, i-1);
         ahc_outb(ahc, SCB_NEXT, SCB_LIST_NULL);
-
- /* Ensure we clear the 0 SCB's control byte. */
- ahc_outb(ahc, SCBPTR, 0);
- ahc_outb(ahc, SCB_CONTROL, 0);
 }
 
 static int
@@ -4234,6 +4315,12 @@
                 }
         }
         printf ("\n");
+ /*
+ * Reading uninitialized scratch ram may
+ * generate parity errors.
+ */
+ ahc_outb(ahc, CLRINT, CLRPARERR);
+ ahc_outb(ahc, CLRINT, CLRBRKADRINT);
 #endif
         max_targ = 15;
 
@@ -4425,7 +4512,7 @@
         tagenable = ALL_TARGETS_MASK;
 
         /* Grab the disconnection disable table and invert it for our needs */
- if (ahc->flags & AHC_USEDEFAULTS) {
+ if ((ahc->flags & AHC_USEDEFAULTS) != 0) {
                 printf("%s: Host Adapter Bios disabled. Using default SCSI "
                         "device parameters\n", ahc_name(ahc));
                 ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B|
@@ -5068,11 +5155,10 @@
         uint8_t qinstart;
         uint8_t qinpos;
         uint8_t qintail;
- uint8_t next, prev;
+ uint8_t next;
+ uint8_t prev;
         uint8_t curscbptr;
         int found;
- int maxtarget;
- int i;
         int have_qregs;
 
         qintail = ahc->qinfifonext;
@@ -5083,7 +5169,6 @@
         } else
                 qinstart = ahc_inb(ahc, QINPOS);
         qinpos = qinstart;
- next = ahc_inb(ahc, NEXT_QUEUED_SCB);
         found = 0;
         prev_scb = NULL;
 
@@ -5123,8 +5208,7 @@
 
                                 ostat = ahc_get_transaction_status(scb);
                                 if (ostat == CAM_REQ_INPROG)
- ahc_set_transaction_status(scb,
- status);
+ ahc_set_transaction_status(scb, status);
                                 cstat = ahc_get_transaction_status(scb);
                                 if (cstat != CAM_REQ_CMP)
                                         ahc_freeze_scb(scb);
@@ -5133,9 +5217,9 @@
                                 ahc_done(ahc, scb);
 
                                 /* FALLTHROUGH */
+ }
                         case SEARCH_REMOVE:
                                 break;
- }
                         case SEARCH_COUNT:
                                 ahc_qinfifo_requeue(ahc, prev_scb, scb);
                                 prev_scb = scb;
@@ -5262,9 +5346,33 @@
         }
         ahc_outb(ahc, SCBPTR, curscbptr);
 
- /*
- * And lastly, the untagged holding queues.
- */
+ found += ahc_search_untagged_queues(ahc, /*ahc_io_ctx_t*/NULL, target,
+ channel, lun, status, action);
+
+ if (action == SEARCH_COMPLETE)
+ ahc_release_untagged_queues(ahc);
+ return (found);
+}
+
+int
+ahc_search_untagged_queues(struct ahc_softc *ahc, ahc_io_ctx_t ctx,
+ int target, char channel, int lun, uint32_t status,
+ ahc_search_action action)
+{
+ struct scb *scb;
+ int maxtarget;
+ int found;
+ int i;
+
+ if (action == SEARCH_COMPLETE) {
+ /*
+ * Don't attempt to run any queued untagged transactions
+ * until we are done with the abort process.
+ */
+ ahc_freeze_untagged_queues(ahc);
+ }
+
+ found = 0;
         i = 0;
         if ((ahc->flags & AHC_SCB_BTT) == 0) {
 
@@ -5303,37 +5411,37 @@
                         if ((scb->flags & SCB_ACTIVE) != 0)
                                 continue;
 
- if (ahc_match_scb(ahc, scb, target, channel,
- lun, SCB_LIST_NULL, role)) {
- /*
- * We found an scb that needs to be acted on.
- */
- found++;
- switch (action) {
- case SEARCH_COMPLETE:
- {
- cam_status ostat;
- cam_status cstat;
-
- ostat = ahc_get_transaction_status(scb);
- if (ostat == CAM_REQ_INPROG)
- ahc_set_transaction_status(scb,
- status);
- cstat = ahc_get_transaction_status(scb);
- if (cstat != CAM_REQ_CMP)
- ahc_freeze_scb(scb);
- if ((scb->flags & SCB_ACTIVE) == 0)
- printf("Inactive SCB in untaggedQ\n");
- ahc_done(ahc, scb);
- break;
- }
- case SEARCH_REMOVE:
- TAILQ_REMOVE(untagged_q, scb,
- links.tqe);
- break;
- case SEARCH_COUNT:
- break;
- }
+ if (ahc_match_scb(ahc, scb, target, channel, lun,
+ SCB_LIST_NULL, ROLE_INITIATOR) == 0
+ || (ctx != NULL && ctx != scb->io_ctx))
+ continue;
+
+ /*
+ * We found an scb that needs to be acted on.
+ */
+ found++;
+ switch (action) {
+ case SEARCH_COMPLETE:
+ {
+ cam_status ostat;
+ cam_status cstat;
+
+ ostat = ahc_get_transaction_status(scb);
+ if (ostat == CAM_REQ_INPROG)
+ ahc_set_transaction_status(scb, status);
+ cstat = ahc_get_transaction_status(scb);
+ if (cstat != CAM_REQ_CMP)
+ ahc_freeze_scb(scb);
+ if ((scb->flags & SCB_ACTIVE) == 0)
+ printf("Inactive SCB in untaggedQ\n");
+ ahc_done(ahc, scb);
+ break;
+ }
+ case SEARCH_REMOVE:
+ TAILQ_REMOVE(untagged_q, scb, links.tqe);
+ break;
+ case SEARCH_COUNT:
+ break;
                         }
                 }
         }
@@ -5646,6 +5754,7 @@
         ahc_outb(ahc, SIMODE1, ahc_inb(ahc, SIMODE1) & ~ENSCSIRST);
         scsiseq = ahc_inb(ahc, SCSISEQ);
         ahc_outb(ahc, SCSISEQ, scsiseq | SCSIRSTO);
+ ahc_flush_device_writes(ahc);
         ahc_delay(AHC_BUSRESET_DELAY);
         /* Turn off the bus reset */
         ahc_outb(ahc, SCSISEQ, scsiseq & ~SCSIRSTO);
@@ -5687,6 +5796,16 @@
          */
         ahc_run_qoutfifo(ahc);
 #if AHC_TARGET_MODE
+ /*
+ * XXX - In Twin mode, the tqinfifo may have commands
+ * for an unaffected channel in it. However, if
+ * we have run out of ATIO resources to drain that
+ * queue, we may not get them all out here. Further,
+ * the blocked transactions for the reset channel
+ * should just be killed off, irrespecitve of whether
+ * we are blocked on ATIO resources. Write a routine
+ * to compact the tqinfifo appropriately.
+ */
         if ((ahc->flags & AHC_TARGETROLE) != 0) {
                 ahc_run_tqinfifo(ahc, /*paused*/TRUE);
         }
@@ -5708,10 +5827,6 @@
                  */
                 ahc_outb(ahc, SBLKCTL, sblkctl ^ SELBUSB);
                 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
- ahc_outb(ahc, SIMODE1, simode1);
- if (initiate_reset)
- ahc_reset_current_bus(ahc);
- ahc_clear_intstat(ahc);
 #if AHC_TARGET_MODE
                 /*
                  * Bus resets clear ENSELI, so we cannot
@@ -5719,19 +5834,18 @@
                  * if we are in target mode.
                  */
                 if ((ahc->flags & AHC_TARGETROLE) != 0)
- ahc_outb(ahc, SIMODE1, simode1 | ENSCSIRST);
+ simode1 |= ENSCSIRST;
 #endif
+ ahc_outb(ahc, SIMODE1, simode1);
+ if (initiate_reset)
+ ahc_reset_current_bus(ahc);
+ ahc_clear_intstat(ahc);
                 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
                 ahc_outb(ahc, SBLKCTL, sblkctl);
                 restart_needed = FALSE;
         } else {
                 /* Case 2: A command from this bus is active or we're idle */
- ahc_clear_msg_state(ahc);
                 simode1 = ahc_inb(ahc, SIMODE1) & ~(ENBUSFREE|ENSCSIRST);
- ahc_outb(ahc, SIMODE1, simode1);
- if (initiate_reset)
- ahc_reset_current_bus(ahc);
- ahc_clear_intstat(ahc);
 #if AHC_TARGET_MODE
                 /*
                  * Bus resets clear ENSELI, so we cannot
@@ -5739,8 +5853,12 @@
                  * if we are in target mode.
                  */
                 if ((ahc->flags & AHC_TARGETROLE) != 0)
- ahc_outb(ahc, SIMODE1, simode1 | ENSCSIRST);
+ simode1 |= ENSCSIRST;
 #endif
+ ahc_outb(ahc, SIMODE1, simode1);
+ if (initiate_reset)
+ ahc_reset_current_bus(ahc);
+ ahc_clear_intstat(ahc);
                 ahc_outb(ahc, SCSISEQ, scsiseq & (ENSELI|ENRSELI|ENAUTOATNP));
                 restart_needed = TRUE;
         }
@@ -5819,7 +5937,7 @@
  * Calculate the residual for a just completed SCB.
  */
 void
-ahc_calc_residual(struct scb *scb)
+ahc_calc_residual(struct ahc_softc *ahc, struct scb *scb)
 {
         struct hardware_scb *hscb;
         struct status_pkt *spkt;
@@ -6299,7 +6417,8 @@
         printf("ACCUM = 0x%x, SINDEX = 0x%x, DINDEX = 0x%x, ARG_2 = 0x%x\n",
                ahc_inb(ahc, ACCUM), ahc_inb(ahc, SINDEX), ahc_inb(ahc, DINDEX),
                ahc_inb(ahc, ARG_2));
- printf("HCNT = 0x%x\n", ahc_inb(ahc, HCNT));
+ printf("HCNT = 0x%x SCBPTR = 0x%x\n", ahc_inb(ahc, HCNT),
+ ahc_inb(ahc, SCBPTR));
         printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x\n",
                ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL));
         printf(" DFCNTRL = 0x%x, DFSTATUS = 0x%x\n",
@@ -6372,6 +6491,17 @@
         }
         printf("\n");
 
+ printf("Sequencer SCB Info: ");
+ for (i = 0; i < ahc->scb_data->maxhscbs; i++) {
+ ahc_outb(ahc, SCBPTR, i);
+ printf("%d(c 0x%x, s 0x%x, l %d, t 0x%x) ",
+ i, ahc_inb(ahc, SCB_CONTROL),
+ ahc_inb(ahc, SCB_SCSIID),
+ ahc_inb(ahc, SCB_LUN),
+ ahc_inb(ahc, SCB_TAG));
+ }
+ printf("\n");
+
         printf("Pending list: ");
         i = 0;
         LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
@@ -6379,7 +6509,8 @@
                         break;
                 if (scb != LIST_FIRST(&ahc->pending_scbs))
                         printf(", ");
- printf("%d", scb->hscb->tag);
+ printf("%d(c 0x%x, s 0x%x, l %d)", scb->hscb->tag,
+ scb->hscb->control, scb->hscb->scsiid, scb->hscb->lun);
                 if ((ahc->flags & AHC_PAGESCBS) == 0) {
                         ahc_outb(ahc, SCBPTR, scb->hscb->tag);
                         printf("(0x%x, 0x%x)", ahc_inb(ahc, SCB_CONTROL),
@@ -6907,6 +7038,8 @@
                 /*
                  * Wait for more ATIOs from the peripheral driver for this lun.
                  */
+ if (bootverbose)
+ printf("%s: ATIOs exhausted\n", ahc_name(ahc));
                 return (1);
         } else
                 ahc->flags &= ~AHC_TQINFIFO_BLOCKED;
===== drivers/scsi/aic7xxx/aic7xxx.h 1.4 vs edited =====
--- 1.4/drivers/scsi/aic7xxx/aic7xxx.h Tue Feb 5 16:53:47 2002
+++ edited/drivers/scsi/aic7xxx/aic7xxx.h Thu Oct 24 13:13:51 2002
@@ -37,9 +37,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#34 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.h#45 $
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.30 2000/11/10 20:13:40 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.h,v 1.16.2.13 2002/04/29 19:36:29 gibbs Exp $
  */
 
 #ifndef _AIC7XXX_H_
@@ -51,6 +51,7 @@
 /************************* Forward Declarations *******************************/
 struct ahc_platform_data;
 struct scb_platform_data;
+struct seeprom_descriptor;
 
 /****************************** Useful Macros *********************************/
 #ifndef MAX
@@ -350,9 +351,11 @@
                                            */
         AHC_BIOS_ENABLED = 0x80000,
         AHC_ALL_INTERRUPTS = 0x100000,
- AHC_PAGESCBS = 0x400000, /* Enable SCB paging */
- AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */
- AHC_39BIT_ADDRESSING = 0x1000000 /* Use 39 bit addressing scheme. */
+ AHC_PAGESCBS = 0x400000, /* Enable SCB paging */
+ AHC_EDGE_INTERRUPT = 0x800000, /* Device uses edge triggered ints */
+ AHC_39BIT_ADDRESSING = 0x1000000, /* Use 39 bit addressing scheme. */
+ AHC_LSCBS_ENABLED = 0x2000000, /* 64Byte SCBs enabled */
+ AHC_SCB_CONFIG_USED = 0x4000000 /* No SEEPROM but SCB2 had info. */
 } ahc_flag;
 
 /************************* Hardware SCB Definition ***************************/
@@ -941,6 +944,7 @@
         ahc_feature features;
         ahc_bug bugs;
         ahc_flag flags;
+ struct seeprom_config *seep_config;
 
         /* Values to store in the SEQCTL register for pause and unpause */
         uint8_t unpause;
@@ -1093,7 +1097,8 @@
 /*************************** EISA/VL Front End ********************************/
 struct aic7770_identity *aic7770_find_device(uint32_t);
 int aic7770_config(struct ahc_softc *ahc,
- struct aic7770_identity *);
+ struct aic7770_identity *,
+ u_int port);
 
 /************************** SCB and SCB queue management **********************/
 int ahc_probe_scbs(struct ahc_softc *);
@@ -1116,6 +1121,7 @@
 int ahc_suspend(struct ahc_softc *ahc);
 int ahc_resume(struct ahc_softc *ahc);
 void ahc_softc_insert(struct ahc_softc *);
+struct ahc_softc *ahc_find_softc(struct ahc_softc *ahc);
 void ahc_set_unit(struct ahc_softc *, int);
 void ahc_set_name(struct ahc_softc *, char *);
 void ahc_alloc_scbs(struct ahc_softc *ahc);
@@ -1146,6 +1152,11 @@
                                            char channel, int lun, u_int tag,
                                            role_t role, uint32_t status,
                                            ahc_search_action action);
+int ahc_search_untagged_queues(struct ahc_softc *ahc,
+ ahc_io_ctx_t ctx,
+ int target, char channel,
+ int lun, uint32_t status,
+ ahc_search_action action);
 int ahc_search_disc_list(struct ahc_softc *ahc, int target,
                                              char channel, int lun, u_int tag,
                                              int stop_on_first, int remove,
@@ -1157,7 +1168,8 @@
                                        char channel, int lun, u_int tag,
                                        role_t role, uint32_t status);
 void ahc_restart(struct ahc_softc *ahc);
-void ahc_calc_residual(struct scb *scb);
+void ahc_calc_residual(struct ahc_softc *ahc,
+ struct scb *scb);
 /*************************** Utility Functions ********************************/
 struct ahc_phase_table_entry*
                         ahc_lookup_phase_entry(int phase);
@@ -1219,6 +1231,15 @@
 #endif
 #endif
 /******************************* Debug ***************************************/
+#ifdef AHC_DEBUG
+extern int ahc_debug;
+#define AHC_SHOWMISC 0x1
+#define AHC_SHOWSENSE 0x2
+#endif
 void ahc_print_scb(struct scb *scb);
 void ahc_dump_card_state(struct ahc_softc *ahc);
+/******************************* SEEPROM *************************************/
+int ahc_acquire_seeprom(struct ahc_softc *ahc,
+ struct seeprom_descriptor *sd);
+void ahc_release_seeprom(struct seeprom_descriptor *sd);
 #endif /* _AIC7XXX_H_ */
===== drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped 1.6 vs edited =====
--- 1.6/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped Tue Jun 18 11:55:42 2002
+++ edited/drivers/scsi/aic7xxx/aic7xxx_reg.h_shipped Thu Oct 24 13:51:53 2002
@@ -2,8 +2,8 @@
  * DO NOT EDIT - This file is automatically generated
  * from the following source files:
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 $
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $
  */
 
 #define SCSISEQ 0x00
@@ -184,7 +184,7 @@
 #define SOFT1 0x80
 #define SOFT0 0x40
 #define SOFTCMDEN 0x20
-#define HAS_BRDCTL 0x10
+#define EXT_BRDCTL 0x10
 #define SEEPROM 0x08
 #define EEPROM 0x04
 #define ROM 0x02
@@ -228,8 +228,6 @@
 #define BUSY_TARGETS 0x20
 #define TARG_SCSIRATE 0x20
 
-#define SRAM_BASE 0x20
-
 #define ULTRA_ENB 0x30
 #define CMDSIZE_TABLE 0x30
 
@@ -329,7 +327,9 @@
 
 #define DATA_COUNT_ODD 0x55
 
+#define HA_274_BIOSGLOBAL 0x56
 #define INITIATOR_TAG 0x56
+#define HA_274_EXTENDED_TRANS 0x01
 
 #define SEQ_FLAGS2 0x57
 #define TARGET_MSG_PENDING 0x02
@@ -396,6 +396,8 @@
 
 #define TARG_OFFSET 0x70
 
+#define SRAM_BASE 0x70
+
 #define BCTL 0x84
 #define ACE 0x08
 #define ENABLE 0x01
@@ -714,3 +716,7 @@
 #define SG_PREFETCH_CNT 0x04
 #define CACHESIZE_MASK 0x02
 #define QINFIFO_OFFSET 0x01
+#define DOWNLOAD_CONST_COUNT 0x07
+
+
+/* Exported Labels */
===== drivers/scsi/aic7xxx/aic7xxx.seq 1.5 vs edited =====
--- 1.5/drivers/scsi/aic7xxx/aic7xxx.seq Tue Feb 5 16:53:47 2002
+++ edited/drivers/scsi/aic7xxx/aic7xxx.seq Thu Oct 24 14:10:37 2002
@@ -37,10 +37,11 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.106 2000/11/12 05:19:46 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.seq,v 1.94.2.16 2002/04/29 19:36:30 gibbs Exp $
  */
 
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#37 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.seq#43 $"
+PATCH_ARG_LIST = "struct ahc_softc *ahc"
 
 #include "aic7xxx.reg"
 #include "scsi_message.h"
@@ -89,7 +90,7 @@
         test SSTAT0, SELDO|SELDI jnz selection;
 test_queue:
         /* Has the driver posted any work for us? */
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
         if ((ahc->features & AHC_QUEUE_REGS) != 0) {
                 test QOFF_CTLSTA, SCB_AVAIL jz poll_for_work_loop;
         } else {
@@ -110,7 +111,7 @@
                 mov SCBPTR, ARG_1;
         }
         or SEQ_FLAGS2, SCB_DMA;
-END_CRITICAL
+END_CRITICAL;
 dma_queued_scb:
         /*
          * DMA the SCB from host ram into the current SCB location.
@@ -124,7 +125,7 @@
          * value.
          */
         mov A, ARG_1;
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
         cmp NEXT_QUEUED_SCB, A jne abort_qinscb;
         if ((ahc->flags & AHC_SEQUENCER_DEBUG) != 0) {
                 cmp SCB_TAG, A je . + 2;
@@ -139,7 +140,7 @@
                 inc QINPOS;
         }
         and SEQ_FLAGS2, ~SCB_DMA;
-END_CRITICAL
+END_CRITICAL;
 start_waiting:
         /*
          * Start the first entry on the waiting SCB list.
@@ -437,7 +438,6 @@
 select_out:
         /* Turn off the selection hardware */
         and SCSISEQ, TEMODE|ENSELI|ENRSELI|ENAUTOATNP, SCSISEQ;
- mvi CLRSINT0, CLRSELDO;
         mov SCBPTR, WAITING_SCBH;
         mov WAITING_SCBH,SCB_NEXT;
         mov SAVED_SCSIID, SCB_SCSIID;
@@ -452,6 +452,7 @@
                  * sending our identify messages.
                  */
                 mvi P_MESGIN|BSYO call change_phase;
+ mvi CLRSINT0, CLRSELDO;
 
                 /*
                  * Start out with a simple identify message.
@@ -498,6 +499,7 @@
                 }
                 mvi DMAPARAMS, HDMAEN|DIRECTION|FIFORESET;
                 mov SCB_TAG call dma_scb;
+ call set_transfer_settings;
                 jmp target_synccmd;
 
 target_mesgout:
@@ -641,6 +643,7 @@
          */
         mvi MSG_OUT, MSG_IDENTIFYFLAG;
         or SEQ_FLAGS, IDENTIFY_SEEN;
+ mvi CLRSINT0, CLRSELDO;
 
         /*
          * Main loop for information transfer phases. Wait for the
@@ -968,12 +971,12 @@
 ultra2_ensure_sg:
                 test SG_CACHE_SHADOW, LAST_SEG jz ultra2_shvalid;
                 /* Record if we've consumed all S/G entries */
- test SSTAT2, SHVALID jnz residuals_correct;
+ test SSTAT2, SHVALID jnz residuals_correct;
                 or SCB_RESIDUAL_SGPTR[0], SG_LIST_NULL;
                 jmp residuals_correct;
 
 ultra2_shvalid:
- test SSTAT2, SHVALID jnz sgptr_fixup;
+ test SSTAT2, SHVALID jnz sgptr_fixup;
                 call idle_loop;
                 jmp ultra2_ensure_sg;
 
@@ -1397,7 +1400,7 @@
          * The data fifo seems to require 4 byte aligned
          * transfers from the sequencer. Force this to
          * be the case by clearing HADDR[0] even though
- * we aren't going to touch host memeory.
+ * we aren't going to touch host memory.
          */
         clr HADDR[0];
         if ((ahc->features & AHC_ULTRA2) != 0) {
@@ -2003,7 +2006,7 @@
  * removal of the found SCB from the disconnected list.
  */
 if ((ahc->flags & AHC_PAGESCBS) != 0) {
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 findSCB:
         mov A, SINDEX; /* Tag passed in SINDEX */
         cmp DISCONNECTED_SCBH, SCB_LIST_NULL je findSCB_notFound;
@@ -2025,7 +2028,7 @@
         mov SCBPTR, SINDEX ret;
 rHead:
         mov DISCONNECTED_SCBH,SCB_NEXT ret;
-END_CRITICAL
+END_CRITICAL;
 findSCB_notFound:
         /*
          * We didn't find it. Page in the SCB.
@@ -2150,7 +2153,7 @@
         adc DINDIR, A, SINDIR ret;
 
 /*
- * Either post or fetch and SCB from host memory based on the
+ * Either post or fetch an SCB from host memory based on the
  * DIRECTION bit in DMAPARAMS. The host SCB index is in SINDEX.
  */
 dma_scb:
@@ -2308,11 +2311,11 @@
         }
 add_scb_to_free_list:
         if ((ahc->flags & AHC_PAGESCBS) != 0) {
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
                 mov SCB_NEXT, FREE_SCBH;
                 mvi SCB_TAG, SCB_LIST_NULL;
                 mov FREE_SCBH, SCBPTR ret;
-END_CRITICAL
+END_CRITICAL;
         } else {
                 mvi SCB_TAG, SCB_LIST_NULL ret;
         }
@@ -2326,7 +2329,7 @@
 
 if ((ahc->flags & AHC_PAGESCBS) != 0) {
 get_free_or_disc_scb:
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
         cmp FREE_SCBH, SCB_LIST_NULL jne dequeue_free_scb;
         cmp DISCONNECTED_SCBH, SCB_LIST_NULL jne dequeue_disc_scb;
 return_error:
@@ -2335,14 +2338,14 @@
 dequeue_disc_scb:
         mov SCBPTR, DISCONNECTED_SCBH;
         mov DISCONNECTED_SCBH, SCB_NEXT;
-END_CRITICAL
+END_CRITICAL;
         mvi DMAPARAMS, FIFORESET;
         mov SCB_TAG jmp dma_scb;
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
 dequeue_free_scb:
         mov SCBPTR, FREE_SCBH;
         mov FREE_SCBH, SCB_NEXT ret;
-END_CRITICAL
+END_CRITICAL;
 
 add_scb_to_disc_list:
 /*
@@ -2350,10 +2353,10 @@
  * candidates for paging out an SCB if one is needed for a new command.
  * Modifying the disconnected list is a critical(pause dissabled) section.
  */
-BEGIN_CRITICAL
+BEGIN_CRITICAL;
         mov SCB_NEXT, DISCONNECTED_SCBH;
         mov DISCONNECTED_SCBH, SCBPTR ret;
-END_CRITICAL
+END_CRITICAL;
 }
 set_seqint:
         mov INTSTAT, SINDEX;
===== drivers/scsi/aic7xxx/aic7770_linux.c 1.4 vs edited =====
--- 1.4/drivers/scsi/aic7xxx/aic7770_linux.c Tue Feb 5 16:53:47 2002
+++ edited/drivers/scsi/aic7xxx/aic7770_linux.c Wed Oct 23 14:28:43 2002
@@ -55,9 +55,6 @@
         int eisaBase;
         int found;
 
- if (aic7xxx_no_probe)
- return (0);
-
         eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET;
         found = 0;
         for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) {
@@ -103,9 +100,7 @@
                                  */
                                 break;
                         }
- ahc->tag = BUS_SPACE_PIO;
- ahc->bsh.ioport = eisaBase;
- error = aic7770_config(ahc, entry);
+ error = aic7770_config(ahc, entry, eisaBase);
                         if (error != 0) {
                                 ahc_free(ahc);
                                 continue;
@@ -120,18 +115,19 @@
 }
 
 int
-aic7770_map_registers(struct ahc_softc *ahc)
+aic7770_map_registers(struct ahc_softc *ahc, u_int port)
 {
         /*
          * Lock out other contenders for our i/o space.
          */
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
- request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx");
+ request_region(port, AHC_EISA_IOSIZE, "aic7xxx");
 #else
- if (request_region(ahc->bsh.ioport, AHC_EISA_IOSIZE, "aic7xxx") == 0)
+ if (request_region(port, AHC_EISA_IOSIZE, "aic7xxx") == 0)
                 return (ENOMEM);
 #endif
-
+ ahc->tag = BUS_SPACE_PIO;
+ ahc->bsh.ioport = port;
         return (0);
 }
 
@@ -145,9 +141,9 @@
         if ((ahc->flags & AHC_EDGE_INTERRUPT) == 0)
                 shared = SA_SHIRQ;
 
- ahc->platform_data->irq = irq;
- error = request_irq(ahc->platform_data->irq, ahc_linux_isr,
- shared, "aic7xxx", ahc);
+ error = request_irq(irq, ahc_linux_isr, shared, "aic7xxx", ahc);
+ if (error == 0)
+ ahc->platform_data->irq = irq;
         
         return (-error);
 }
===== drivers/scsi/aic7xxx/aic7770.c 1.5 vs edited =====
--- 1.5/drivers/scsi/aic7xxx/aic7770.c Tue Feb 5 16:53:47 2002
+++ edited/drivers/scsi/aic7xxx/aic7770.c Thu Oct 24 13:12:44 2002
@@ -37,7 +37,7 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#14 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7770.c#21 $
  *
  * $FreeBSD: src/sys/dev/aic7xxx/aic7770.c,v 1.1 2000/09/16 20:02:27 gibbs Exp $
  */
@@ -51,7 +51,7 @@
 #define ID_AHA_284xB 0x04907756 /* BIOS enabled */
 #define ID_AHA_284x 0x04907757 /* BIOS disabled*/
 
-static void aha2840_load_seeprom(struct ahc_softc *ahc);
+static int aha2840_load_seeprom(struct ahc_softc *ahc);
 static ahc_device_setup_t ahc_aic7770_VL_setup;
 static ahc_device_setup_t ahc_aic7770_EISA_setup;;
 static ahc_device_setup_t ahc_aic7770_setup;
@@ -96,21 +96,33 @@
 }
 
 int
-aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry)
+aic7770_config(struct ahc_softc *ahc, struct aic7770_identity *entry, u_int io)
 {
+ u_long l;
+ u_long s;
         int error;
+ int have_seeprom;
         u_int hostconf;
         u_int irq;
         u_int intdef;
 
         error = entry->setup(ahc);
+ have_seeprom = 0;
         if (error != 0)
                 return (error);
 
- error = aic7770_map_registers(ahc);
+ error = aic7770_map_registers(ahc, io);
         if (error != 0)
                 return (error);
 
+ /*
+ * Before we continue probing the card, ensure that
+ * its interrupts are *disabled*. We don't want
+ * a misstep to hang the machine in an interrupt
+ * storm.
+ */
+ ahc_intr_enable(ahc, FALSE);
+
         ahc->description = entry->name;
         error = ahc_softc_init(ahc);
 
@@ -168,21 +180,22 @@
                                         ahc->flags |= AHC_TERM_ENB_B;
                         }
                 }
- /*
- * We have no way to tell, so assume extended
- * translation is enabled.
- */
- ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
+ if ((ahc_inb(ahc, HA_274_BIOSGLOBAL) & HA_274_EXTENDED_TRANS))
+ ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B;
                 break;
         }
         case AHC_VL:
         {
- aha2840_load_seeprom(ahc);
+ have_seeprom = aha2840_load_seeprom(ahc);
                 break;
         }
         default:
                 break;
         }
+ if (have_seeprom == 0) {
+ free(ahc->seep_config, M_DEVBUF);
+ ahc->seep_config = NULL;
+ }
 
         /*
          * Ensure autoflush is enabled
@@ -201,15 +214,16 @@
         if (error != 0)
                 return (error);
 
+ error = aic7770_map_int(ahc, irq);
+ if (error != 0)
+ return (error);
+
+ ahc_list_lock(&l);
         /*
          * Link this softc in with all other ahc instances.
          */
         ahc_softc_insert(ahc);
 
- error = aic7770_map_int(ahc, irq);
- if (error != 0)
- return (error);
-
         /*
          * Enable the board's BUS drivers
          */
@@ -218,7 +232,11 @@
         /*
          * Allow interrupts.
          */
+ ahc_lock(ahc, &s);
         ahc_intr_enable(ahc, TRUE);
+ ahc_unlock(ahc, &s);
+
+ ahc_list_unlock(&l);
 
         return (0);
 }
@@ -226,14 +244,13 @@
 /*
  * Read the 284x SEEPROM.
  */
-static void
+static int
 aha2840_load_seeprom(struct ahc_softc *ahc)
 {
- struct seeprom_descriptor sd;
- struct seeprom_config sc;
- uint16_t checksum = 0;
- uint8_t scsi_conf;
- int have_seeprom;
+ struct seeprom_descriptor sd;
+ struct seeprom_config *sc;
+ int have_seeprom;
+ uint8_t scsi_conf;
 
         sd.sd_ahc = ahc;
         sd.sd_control_offset = SEECTL_2840;
@@ -246,23 +263,16 @@
         sd.sd_CK = CK_2840;
         sd.sd_DO = DO_2840;
         sd.sd_DI = DI_2840;
+ sc = ahc->seep_config;
 
         if (bootverbose)
                 printf("%s: Reading SEEPROM...", ahc_name(ahc));
- have_seeprom = read_seeprom(&sd,
- (uint16_t *)&sc,
- /*start_addr*/0,
- sizeof(sc)/2);
+ have_seeprom = ahc_read_seeprom(&sd, (uint16_t *)sc,
+ /*start_addr*/0, sizeof(*sc)/2);
 
         if (have_seeprom) {
- /* Check checksum */
- int i;
- int maxaddr = (sizeof(sc)/2) - 1;
- uint16_t *scarray = (uint16_t *)&sc;
-
- for (i = 0; i < maxaddr; i++)
- checksum = checksum + scarray[i];
- if (checksum != sc.checksum) {
+
+ if (ahc_verify_cksum(sc) == 0) {
                         if(bootverbose)
                                 printf ("checksum error\n");
                         have_seeprom = 0;
@@ -280,41 +290,44 @@
                  * Put the data we've collected down into SRAM
                  * where ahc_init will find it.
                  */
- int i;
- int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
+ int i;
+ int max_targ;
                 uint16_t discenable;
 
+ max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8;
                 discenable = 0;
                 for (i = 0; i < max_targ; i++){
- uint8_t target_settings;
- target_settings = (sc.device_flags[i] & CFXFER) << 4;
- if (sc.device_flags[i] & CFSYNCH)
+ uint8_t target_settings;
+
+ target_settings = (sc->device_flags[i] & CFXFER) << 4;
+ if (sc->device_flags[i] & CFSYNCH)
                                 target_settings |= SOFS;
- if (sc.device_flags[i] & CFWIDEB)
+ if (sc->device_flags[i] & CFWIDEB)
                                 target_settings |= WIDEXFER;
- if (sc.device_flags[i] & CFDISC)
+ if (sc->device_flags[i] & CFDISC)
                                 discenable |= (0x01 << i);
                         ahc_outb(ahc, TARG_SCSIRATE + i, target_settings);
                 }
                 ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff));
                 ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff));
 
- ahc->our_id = sc.brtime_id & CFSCSIID;
+ ahc->our_id = sc->brtime_id & CFSCSIID;
 
                 scsi_conf = (ahc->our_id & 0x7);
- if (sc.adapter_control & CFSPARITY)
+ if (sc->adapter_control & CFSPARITY)
                         scsi_conf |= ENSPCHK;
- if (sc.adapter_control & CFRESETB)
+ if (sc->adapter_control & CFRESETB)
                         scsi_conf |= RESET_SCSI;
 
- if (sc.bios_control & CF284XEXTEND)
+ if (sc->bios_control & CF284XEXTEND)
                         ahc->flags |= AHC_EXTENDED_TRANS_A;
                 /* Set SCSICONF info */
                 ahc_outb(ahc, SCSICONF, scsi_conf);
 
- if (sc.adapter_control & CF284XSTERM)
+ if (sc->adapter_control & CF284XSTERM)
                         ahc->flags |= AHC_TERM_ENB_A;
         }
+ return (have_seeprom);
 }
 
 static int
===== drivers/scsi/aic7xxx/aic7xxx.reg 1.5 vs edited =====
--- 1.5/drivers/scsi/aic7xxx/aic7xxx.reg Tue Feb 5 16:53:47 2002
+++ edited/drivers/scsi/aic7xxx/aic7xxx.reg Thu Oct 24 13:14:53 2002
@@ -37,9 +37,9 @@
  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGES.
  *
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.31 2000/11/10 20:13:40 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx.reg,v 1.20.2.11 2002/04/29 19:36:30 gibbs Exp $
  */
-VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#24 $"
+VERSION = "$Id: //depot/aic7xxx/aic7xxx/aic7xxx.reg#30 $"
 
 /*
  * This file is processed by the aic7xxx_asm utility for use in assembling
@@ -474,7 +474,7 @@
         bit SOFT1 0x80
         bit SOFT0 0x40
         bit SOFTCMDEN 0x20
- bit HAS_BRDCTL 0x10 /* External Board control */
+ bit EXT_BRDCTL 0x10 /* External Board control */
         bit SEEPROM 0x08 /* External serial eeprom logic */
         bit EEPROM 0x04 /* Writable external BIOS ROM */
         bit ROM 0x02 /* Logic for accessing external ROM */
@@ -1009,7 +1009,9 @@
  * SCB Definition (p. 5-4)
  */
 scb {
- address 0x0a0
+ address 0x0a0
+ size 64
+
         SCB_CDB_PTR {
                 size 4
                 alias SCB_RESIDUAL_DATACNT
@@ -1254,7 +1256,8 @@
  */
 
 scratch_ram {
- address 0x020
+ address 0x020
+ size 58
 
         /*
          * 1 byte per target starting at this address for configuration values
@@ -1316,7 +1319,7 @@
                 bit SDMAENACK 0x10
                 bit HDMAEN 0x08
                 bit HDMAENACK 0x08
- bit DIRECTION 0x04
+ bit DIRECTION 0x04 /* Set indicates PCI->SCSI */
                 bit FIFOFLUSH 0x02
                 bit FIFORESET 0x01
         }
@@ -1469,26 +1472,46 @@
         DATA_COUNT_ODD {
                 size 1
         }
+}
+
+scratch_ram {
+ address 0x056
+ size 4
+ /*
+ * These scratch ram locations are initialized by the 274X BIOS.
+ * We reuse them after capturing the BIOS settings during
+ * initialization.
+ */
 
         /*
          * The initiator specified tag for this target mode transaction.
          */
- INITIATOR_TAG {
- size 1
+ HA_274_BIOSGLOBAL {
+ size 1
+ bit HA_274_EXTENDED_TRANS 0x01
+ alias INITIATOR_TAG
         }
 
         SEQ_FLAGS2 {
- size 1
- bit SCB_DMA 0x01
- bit TARGET_MSG_PENDING 0x02
+ size 1
+ bit SCB_DMA 0x01
+ bit TARGET_MSG_PENDING 0x02
         }
+}
+
+scratch_ram {
+ address 0x05a
+ size 6
         /*
- * These are reserved registers in the card's scratch ram. Some of
- * the values are specified in the AHA2742 technical reference manual
- * and are initialized by the BIOS at boot time.
+ * These are reserved registers in the card's scratch ram on the 2742.
+ * The EISA configuraiton chip is mapped here. On Rev E. of the
+ * aic7770, the sequencer can use this area for scratch, but the
+ * host cannot directly access these registers. On later chips, this
+ * area can be read and written by both the host and the sequencer.
+ * Even on later chips, many of these locations are initialized by
+ * the BIOS.
          */
         SCSICONF {
- address 0x05a
                 size 1
                 bit TERM_ENB 0x80
                 bit RESET_SCSI 0x40
@@ -1513,11 +1536,16 @@
                 mask BIOSDISABLED 0x30
                 bit CHANNEL_B_PRIMARY 0x08
         }
+}
+
+scratch_ram {
+ address 0x070
+ size 16
+
         /*
          * Per target SCSI offset values for Ultra2 controllers.
          */
         TARG_OFFSET {
- address 0x070
                 size 16
         }
 }

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Thu Oct 31 2002 - 22:00:26 EST