diff options
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.c | 51 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx.seq | 180 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_freebsd.c | 8 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_inline.h | 2 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_osm.c | 8 | ||||
-rw-r--r-- | sys/dev/aic7xxx/aic7xxx_pci.c | 67 |
6 files changed, 194 insertions, 122 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.c b/sys/dev/aic7xxx/aic7xxx.c index c7a9d95..d0d0bcd 100644 --- a/sys/dev/aic7xxx/aic7xxx.c +++ b/sys/dev/aic7xxx/aic7xxx.c @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.c#28 $ + * $Id: //depot/src/aic7xxx/aic7xxx.c#30 $ * * $FreeBSD$ */ @@ -887,8 +887,8 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) if ((ahc->features & AHC_TWIN) != 0) { /* Try the other channel */ ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB); - status = ahc_inb(ahc, SSTAT1); - ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB); + status = ahc_inb(ahc, SSTAT1) + & (SELTO|SCSIRSTI|BUSFREE|SCSIPERR); intr_channel = (cur_channel == 'A') ? 'B' : 'A'; } if (status == 0) { @@ -928,6 +928,8 @@ ahc_handle_scsiint(struct ahc_softc *ahc, u_int intstat) } else if ((status & SCSIRSTI) != 0) { printf("%s: Someone reset channel %c\n", ahc_name(ahc), intr_channel); + if (intr_channel != cur_channel) + ahc_outb(ahc, SBLKCTL, ahc_inb(ahc, SBLKCTL) ^ SELBUSB); ahc_reset_channel(ahc, intr_channel, /*Initiate Reset*/FALSE); } else if ((status & SCSIPERR) != 0) { /* @@ -1704,6 +1706,19 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid, devinfo->target, &tstate); + + if ((type & AHC_TRANS_USER) != 0) { + tinfo->user.period = period; + tinfo->user.offset = offset; + tinfo->user.ppr_options = ppr_options; + } + + if ((type & AHC_TRANS_GOAL) != 0) { + tinfo->goal.period = period; + tinfo->goal.offset = offset; + tinfo->goal.ppr_options = ppr_options; + } + old_period = tinfo->current.period; old_offset = tinfo->current.offset; old_ppr = tinfo->current.ppr_options; @@ -1782,18 +1797,6 @@ ahc_set_syncrate(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, } } - if ((type & AHC_TRANS_GOAL) != 0) { - tinfo->goal.period = period; - tinfo->goal.offset = offset; - tinfo->goal.ppr_options = ppr_options; - } - - if ((type & AHC_TRANS_USER) != 0) { - tinfo->user.period = period; - tinfo->user.offset = offset; - tinfo->user.ppr_options = ppr_options; - } - ahc_update_target_msg_request(ahc, devinfo, tinfo, /*force*/FALSE, paused); @@ -1818,8 +1821,14 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, tinfo = ahc_fetch_transinfo(ahc, devinfo->channel, devinfo->our_scsiid, devinfo->target, &tstate); - oldwidth = tinfo->current.width; + if ((type & AHC_TRANS_USER) != 0) + tinfo->user.width = width; + + if ((type & AHC_TRANS_GOAL) != 0) + tinfo->goal.width = width; + + oldwidth = tinfo->current.width; if ((type & AHC_TRANS_CUR) != 0 && oldwidth != width) { u_int scsirate; @@ -1843,10 +1852,6 @@ ahc_set_width(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, 8 * (0x01 << width)); } } - if ((type & AHC_TRANS_GOAL) != 0) - tinfo->goal.width = width; - if ((type & AHC_TRANS_USER) != 0) - tinfo->user.width = width; ahc_update_target_msg_request(ahc, devinfo, tinfo, /*force*/FALSE, paused); @@ -3063,7 +3068,8 @@ ahc_handle_msg_reject(struct ahc_softc *ahc, struct ahc_devinfo *devinfo) if ((ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; - untagged_q = &(ahc->untagged_queues[devinfo->target]); + untagged_q = + &(ahc->untagged_queues[devinfo->target_offset]); TAILQ_INSERT_HEAD(untagged_q, scb, links.tqe); scb->flags |= SCB_UNTAGGEDQ; } @@ -5994,6 +6000,9 @@ ahc_dump_card_state(struct ahc_softc *ahc) ahc_name(ahc), ahc_inb(ahc, SEQADDR0) | (ahc_inb(ahc, SEQADDR1) << 8)); + printf("SCSISEQ = 0x%x, SBLKCTL = 0x%x, SSTAT0 0x%x\n", + ahc_inb(ahc, SCSISEQ), ahc_inb(ahc, SBLKCTL), + ahc_inb(ahc, SSTAT0)); printf("SCB count = %d\n", ahc->scb_data->numscbs); printf("Kernel NEXTQSCB = %d\n", ahc->next_queued_scb->hscb->tag); printf("Card NEXTQSCB = %d\n", ahc_inb(ahc, NEXT_QUEUED_SCB)); diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq index 2a3f449..b490f62 100644 --- a/sys/dev/aic7xxx/aic7xxx.seq +++ b/sys/dev/aic7xxx/aic7xxx.seq @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx.seq#19 $ + * $Id: //depot/src/aic7xxx/aic7xxx.seq#20 $ * * $FreeBSD$ */ @@ -67,21 +67,17 @@ poll_for_work: if ((ahc->features & AHC_ULTRA2) != 0) { clr SCSIBUSL; } -poll_for_work_loop: - test SSTAT0, SELDO|SELDI jnz selection; - test SCSISEQ, ENSELO jnz poll_for_work_loop; + test SCSISEQ, ENSELO jnz poll_for_selection; if ((ahc->features & AHC_TWIN) != 0) { - /* - * Twin channel devices cannot handle things like SELTO - * interrupts on the "background" channel. So, if we - * are selecting, keep polling the current channel util - * either a selection or reselection occurs. - */ xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ - test SSTAT0, SELDO|SELDI jnz selection; - xor SBLKCTL,SELBUSB; /* Toggle back */ + test SCSISEQ, ENSELO jnz poll_for_selection; } cmp WAITING_SCBH,SCB_LIST_NULL jne start_waiting; +poll_for_work_loop: + if ((ahc->features & AHC_TWIN) != 0) { + xor SBLKCTL,SELBUSB; /* Toggle to the other bus */ + } + test SSTAT0, SELDO|SELDI jnz selection; test_queue: /* Has the driver posted any work for us? */ BEGIN_CRITICAL @@ -139,67 +135,15 @@ start_waiting: */ mov SCBPTR, WAITING_SCBH; call start_selection; - jmp poll_for_work_loop; - -abort_qinscb: - call add_scb_to_free_list; - jmp poll_for_work_loop; - -start_selection: - /* - * If bus reset interrupts have been disabled (from a previous - * reset), re-enable them now. Resets are only of interest - * when we have outstanding transactions, so we can safely - * defer re-enabling the interrupt until, as an initiator, - * we start sending out transactions again. - */ - test SIMODE1, ENSCSIRST jnz . + 3; - mvi CLRSINT1, CLRSCSIRSTI; - or SIMODE1, ENSCSIRST; - if ((ahc->features & AHC_TWIN) != 0) { - and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */ - test SCB_SCSIID, TWIN_CHNLB jz . + 2; - or SINDEX, SELBUSB; - mov SBLKCTL,SINDEX; /* select channel */ - } -initialize_scsiid: - if ((ahc->features & AHC_ULTRA2) != 0) { - mov SCSIID_ULTRA2, SCB_SCSIID; - } else if ((ahc->features & AHC_TWIN) != 0) { - and SCSIID, TWIN_TID|OID, SCB_SCSIID; - } else { - mov SCSIID, SCB_SCSIID; - } - if ((ahc->flags & AHC_TARGETROLE) != 0) { - mov SINDEX, SCSISEQ_TEMPLATE; - test SCB_CONTROL, TARGET_SCB jz . + 2; - or SINDEX, TEMODE; - mov SCSISEQ, SINDEX ret; - } else { - mov SCSISEQ, SCSISEQ_TEMPLATE ret; - } -/* - * Initialize transfer settings and clear the SCSI channel. - * SINDEX should contain any additional bit's the client wants - * set in SXFRCTL0. We also assume that the current SCB is - * a valid SCB for the target we wish to talk to. - */ -initialize_channel: - or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; -set_transfer_settings: - if ((ahc->features & AHC_ULTRA) != 0) { - test SCB_CONTROL, ULTRAENB jz . + 2; - or SXFRCTL0, FAST20; - } +poll_for_selection: /* - * Initialize SCSIRATE with the appropriate value for this target. + * Twin channel devices cannot handle things like SELTO + * interrupts on the "background" channel. So, while + * selecting, keep polling the current channel until + * either a selection or reselection occurs. */ - if ((ahc->features & AHC_ULTRA2) != 0) { - bmov SCSIRATE, SCB_SCSIRATE, 2 ret; - } else { - mov SCSIRATE, SCB_SCSIRATE ret; - } + test SSTAT0, SELDO|SELDI jz poll_for_selection; selection: /* @@ -385,23 +329,6 @@ tqinfifo_has_space: or SEQ_FLAGS, TARG_CMD_PENDING|IDENTIFY_SEEN; test SCSISIGI, ATNI jnz target_mesgout_pending; jmp target_ITloop; - -/* - * We carefully toggle SPIOEN to allow us to return the - * message byte we receive so it can be checked prior to - * driving REQ on the bus for the next byte. - */ -target_inb: - /* - * Drive REQ on the bus by enabling SCSI PIO. - */ - or SXFRCTL0, SPIOEN; - /* Wait for the byte */ - test SSTAT0, SPIORDY jz .; - /* Prevent our read from triggering another REQ */ - and SXFRCTL0, ~SPIOEN; - /* Save latched contents */ - mov DINDEX, SCSIDATL ret; } if ((ahc->flags & AHC_INITIATORROLE) != 0) { @@ -427,6 +354,85 @@ initiator_reselect: jmp ITloop; } +abort_qinscb: + call add_scb_to_free_list; + jmp poll_for_work_loop; + +start_selection: + /* + * If bus reset interrupts have been disabled (from a previous + * reset), re-enable them now. Resets are only of interest + * when we have outstanding transactions, so we can safely + * defer re-enabling the interrupt until, as an initiator, + * we start sending out transactions again. + */ + test SIMODE1, ENSCSIRST jnz . + 3; + mvi CLRSINT1, CLRSCSIRSTI; + or SIMODE1, ENSCSIRST; + if ((ahc->features & AHC_TWIN) != 0) { + and SINDEX,~SELBUSB,SBLKCTL;/* Clear channel select bit */ + test SCB_SCSIID, TWIN_CHNLB jz . + 2; + or SINDEX, SELBUSB; + mov SBLKCTL,SINDEX; /* select channel */ + } +initialize_scsiid: + if ((ahc->features & AHC_ULTRA2) != 0) { + mov SCSIID_ULTRA2, SCB_SCSIID; + } else if ((ahc->features & AHC_TWIN) != 0) { + and SCSIID, TWIN_TID|OID, SCB_SCSIID; + } else { + mov SCSIID, SCB_SCSIID; + } + if ((ahc->flags & AHC_TARGETROLE) != 0) { + mov SINDEX, SCSISEQ_TEMPLATE; + test SCB_CONTROL, TARGET_SCB jz . + 2; + or SINDEX, TEMODE; + mov SCSISEQ, SINDEX ret; + } else { + mov SCSISEQ, SCSISEQ_TEMPLATE ret; + } + +/* + * Initialize transfer settings and clear the SCSI channel. + * SINDEX should contain any additional bit's the client wants + * set in SXFRCTL0. We also assume that the current SCB is + * a valid SCB for the target we wish to talk to. + */ +initialize_channel: + or SXFRCTL0, SPIOEN|CLRSTCNT|CLRCHN; +set_transfer_settings: + if ((ahc->features & AHC_ULTRA) != 0) { + test SCB_CONTROL, ULTRAENB jz . + 2; + or SXFRCTL0, FAST20; + } + /* + * Initialize SCSIRATE with the appropriate value for this target. + */ + if ((ahc->features & AHC_ULTRA2) != 0) { + bmov SCSIRATE, SCB_SCSIRATE, 2 ret; + } else { + mov SCSIRATE, SCB_SCSIRATE ret; + } + +if ((ahc->flags & AHC_TARGETROLE) != 0) { +/* + * We carefully toggle SPIOEN to allow us to return the + * message byte we receive so it can be checked prior to + * driving REQ on the bus for the next byte. + */ +target_inb: + /* + * Drive REQ on the bus by enabling SCSI PIO. + */ + or SXFRCTL0, SPIOEN; + /* Wait for the byte */ + test SSTAT0, SPIORDY jz .; + /* Prevent our read from triggering another REQ */ + and SXFRCTL0, ~SPIOEN; + /* Save latched contents */ + mov DINDEX, SCSIDATL ret; +} + /* * After the selection, remove this SCB from the "waiting SCB" * list. This is achieved by simply moving our "next" pointer into diff --git a/sys/dev/aic7xxx/aic7xxx_freebsd.c b/sys/dev/aic7xxx/aic7xxx_freebsd.c index c5f9339..1ccf51c 100644 --- a/sys/dev/aic7xxx/aic7xxx_freebsd.c +++ b/sys/dev/aic7xxx/aic7xxx_freebsd.c @@ -265,8 +265,10 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) LIST_REMOVE(scb, pending_links); if ((scb->flags & SCB_UNTAGGEDQ) != 0) { struct scb_tailq *untagged_q; + int target_offset; - untagged_q = &ahc->untagged_queues[ccb->ccb_h.target_id]; + target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); + untagged_q = &ahc->untagged_queues[target_offset]; TAILQ_REMOVE(untagged_q, scb, links.tqe); scb->flags &= ~SCB_UNTAGGEDQ; ahc_run_untagged_queue(ahc, untagged_q); @@ -1223,8 +1225,10 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 && (ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; + int target_offset; - untagged_q = &(ahc->untagged_queues[ccb->ccb_h.target_id]); + target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); + untagged_q = &(ahc->untagged_queues[target_offset]); TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); scb->flags |= SCB_UNTAGGEDQ; if (TAILQ_FIRST(untagged_q) != scb) { diff --git a/sys/dev/aic7xxx/aic7xxx_inline.h b/sys/dev/aic7xxx/aic7xxx_inline.h index 1aa31f2..a13e376 100644 --- a/sys/dev/aic7xxx/aic7xxx_inline.h +++ b/sys/dev/aic7xxx/aic7xxx_inline.h @@ -28,7 +28,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#14 $ + * $Id: //depot/src/aic7xxx/aic7xxx_inline.h#15 $ * * $FreeBSD$ */ diff --git a/sys/dev/aic7xxx/aic7xxx_osm.c b/sys/dev/aic7xxx/aic7xxx_osm.c index c5f9339..1ccf51c 100644 --- a/sys/dev/aic7xxx/aic7xxx_osm.c +++ b/sys/dev/aic7xxx/aic7xxx_osm.c @@ -265,8 +265,10 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) LIST_REMOVE(scb, pending_links); if ((scb->flags & SCB_UNTAGGEDQ) != 0) { struct scb_tailq *untagged_q; + int target_offset; - untagged_q = &ahc->untagged_queues[ccb->ccb_h.target_id]; + target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); + untagged_q = &ahc->untagged_queues[target_offset]; TAILQ_REMOVE(untagged_q, scb, links.tqe); scb->flags &= ~SCB_UNTAGGEDQ; ahc_run_untagged_queue(ahc, untagged_q); @@ -1223,8 +1225,10 @@ ahc_execute_scb(void *arg, bus_dma_segment_t *dm_segs, int nsegments, if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 && (ahc->flags & AHC_SCB_BTT) == 0) { struct scb_tailq *untagged_q; + int target_offset; - untagged_q = &(ahc->untagged_queues[ccb->ccb_h.target_id]); + target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); + untagged_q = &(ahc->untagged_queues[target_offset]); TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); scb->flags |= SCB_UNTAGGEDQ; if (TAILQ_FIRST(untagged_q) != scb) { diff --git a/sys/dev/aic7xxx/aic7xxx_pci.c b/sys/dev/aic7xxx/aic7xxx_pci.c index 9ac27f8..15cf078 100644 --- a/sys/dev/aic7xxx/aic7xxx_pci.c +++ b/sys/dev/aic7xxx/aic7xxx_pci.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#12 $ + * $Id: //depot/src/aic7xxx/aic7xxx_pci.c#16 $ * * $FreeBSD$ */ @@ -66,6 +66,8 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) #define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull #define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull #define ID_9005_GENERIC_MASK 0xFFF0FFFF00000000ull +#define ID_9005_SISL_MASK 0x000FFFFF00000000ull +#define ID_9005_SISL_ID 0x0005900500000000ull #define ID_AIC7850 0x5078900400000000ull #define ID_AHA_2910_15_20_30C 0x5078900478509004ull #define ID_AIC7855 0x5578900400000000ull @@ -101,12 +103,14 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) #define ID_AHA_2940U_CN 0x0078900478009004ull #define ID_AIC7895 0x7895900478959004ull -#define ID_AIC7895_RAID_PORT 0x7893900478939004ull +#define ID_AIC7895_ARO 0x7890900478939004ull +#define ID_AIC7895_ARO_MASK 0xFFF0FFFFFFFFFFFFull #define ID_AHA_2940U_DUAL 0x7895900478919004ull #define ID_AHA_3940AU 0x7895900478929004ull #define ID_AHA_3944AU 0x7895900478949004ull #define ID_AIC7890 0x001F9005000F9005ull +#define ID_AIC7890_ARO 0x00139005000F9005ull #define ID_AAA_131U2 0x0013900500039005ull #define ID_AHA_2930U2 0x0011900501819005ull #define ID_AHA_2940U2B 0x00109005A1009005ull @@ -115,6 +119,7 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) #define ID_AHA_2950U2B 0x00109005E1009005ull #define ID_AIC7892 0x008F9005FFFF9005ull +#define ID_AIC7892_ARO 0x00839005FFFF9005ull #define ID_AHA_29160 0x00809005E2A09005ull #define ID_AHA_29160_CPQ 0x00809005E2A00E11ull #define ID_AHA_29160N 0x0080900562A09005ull @@ -123,12 +128,14 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) #define ID_AHA_19160B 0x0081900562A19005ull #define ID_AIC7896 0x005F9005FFFF9005ull +#define ID_AIC7896_ARO 0x00539005FFFF9005ull #define ID_AHA_3950U2B_0 0x00509005FFFF9005ull #define ID_AHA_3950U2B_1 0x00509005F5009005ull #define ID_AHA_3950U2D_0 0x00519005FFFF9005ull #define ID_AHA_3950U2D_1 0x00519005B5009005ull #define ID_AIC7899 0x00CF9005FFFF9005ull +#define ID_AIC7899_ARO 0x00C39005FFFF9005ull #define ID_AHA_3960D 0x00C09005F6209005ull /* AKA AHA-39160 */ #define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull @@ -158,6 +165,12 @@ ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) #define SUBID_9005_TYPE_LCCARD 0x1 /* Low Cost Card */ #define SUBID_9005_TYPE_RAID 0x3 /* Combined with Raid */ +#define SUBID_9005_TYPE_KNOWN(id) \ + ((((id) & 0xF) == SUBID_9005_TYPE_MB) \ + || (((id) & 0xF) == SUBID_9005_TYPE_CARD) \ + || (((id) & 0xF) == SUBID_9005_TYPE_LCCARD) \ + || (((id) & 0xF) == SUBID_9005_TYPE_RAID)) + #define SUBID_9005_MAXRATE(id) (((id) & 0x30) >> 4) #define SUBID_9005_MAXRATE_ULTRA2 0x0 #define SUBID_9005_MAXRATE_ULTRA 0x1 @@ -358,6 +371,13 @@ struct ahc_pci_identity ahc_pci_ident_table [] = "Adaptec 2940/CN Ultra SCSI adapter", ahc_aic7880_setup }, + /* Ignore all SISL (AAC on MB) based controllers. */ + { + ID_9005_SISL_ID, + ID_9005_SISL_MASK, + NULL, + NULL + }, /* aic7890 based controllers */ { ID_AHA_2930U2, @@ -390,6 +410,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ahc_aic7890_setup }, { + ID_AIC7890_ARO, + ID_ALL_MASK, + "Adaptec aic7890/91 Ultra2 SCSI adapter (ARO)", + ahc_aic7890_setup + }, + { ID_AAA_131U2, ID_ALL_MASK, "Adaptec AAA-131 Ultra2 RAID adapter", @@ -432,6 +458,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = "Adaptec 19160B Ultra160 SCSI adapter", ahc_aic7892_setup }, + { + ID_AIC7892_ARO, + ID_ALL_MASK, + "Adaptec aic7892 Ultra2 SCSI adapter (ARO)", + ahc_aic7892_setup + }, /* aic7895 based controllers */ { ID_AHA_2940U_DUAL, @@ -451,6 +483,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = "Adaptec 3944A Ultra SCSI adapter", ahc_aic7895_setup }, + { + ID_AIC7895_ARO, + ID_AIC7895_ARO_MASK, + "Adaptec aic7895 Ultra SCSI adapter (ARO)", + ahc_aic7895_setup + }, /* aic7896/97 based controllers */ { ID_AHA_3950U2B_0, @@ -476,6 +514,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = "Adaptec 3950D Ultra2 SCSI adapter", ahc_aic7896_setup }, + { + ID_AIC7896_ARO, + ID_ALL_MASK, + "Adaptec aic7896/97 Ultra2 SCSI adapter (ARO)", + ahc_aic7896_setup + }, /* aic7899 based controllers */ { ID_AHA_3960D, @@ -489,6 +533,12 @@ struct ahc_pci_identity ahc_pci_ident_table [] = "Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter", ahc_aic7899_setup }, + { + ID_AIC7899_ARO, + ID_ALL_MASK, + "Adaptec aic7899 Ultra160 SCSI adapter (ARO)", + ahc_aic7899_setup + }, /* Generic chip probes for devices we don't know 'exactly' */ { ID_AIC7850 & ID_DEV_VENDOR_MASK, @@ -545,12 +595,6 @@ struct ahc_pci_identity ahc_pci_ident_table [] = ahc_aic7895_setup }, { - ID_AIC7895_RAID_PORT & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7895 Ultra SCSI adapter (RAID PORT)", - ahc_aic7895_setup - }, - { ID_AIC7896 & ID_9005_GENERIC_MASK, ID_9005_GENERIC_MASK, "Adaptec aic7896/97 Ultra2 SCSI adapter", @@ -670,13 +714,18 @@ ahc_find_pci_device(ahc_dev_softc_t pci) /* If the second function is not hooked up, ignore it. */ if (ahc_get_pci_function(pci) > 0 && subvendor == 0x9005 + && SUBID_9005_TYPE_KNOWN(subdevice) != 0 && SUBID_9005_MFUNCENB(subdevice) == 0) return (NULL); for (i = 0; i < ahc_num_pci_devs; i++) { entry = &ahc_pci_ident_table[i]; - if (entry->full_id == (full_id & entry->id_mask)) + if (entry->full_id == (full_id & entry->id_mask)) { + /* Honor exclusion entries. */ + if (entry->name == NULL) + return (NULL); return (entry); + } } return (NULL); } |