diff options
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx.h | 27 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_core.c | 30 | ||||
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_inline.h | 34 |
3 files changed, 58 insertions, 33 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx.h b/drivers/scsi/aic7xxx/aic79xx.h index 653fb0b42aea..ac3d07a2a286 100644 --- a/drivers/scsi/aic7xxx/aic79xx.h +++ b/drivers/scsi/aic7xxx/aic79xx.h @@ -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/aic79xx.h#95 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $ * * $FreeBSD$ */ @@ -1062,6 +1062,7 @@ struct ahd_softc { struct scb_data scb_data; struct hardware_scb *next_queued_hscb; + struct map_node *next_queued_hscb_map; /* * SCBs that have been sent to the controller @@ -1140,10 +1141,6 @@ struct ahd_softc { ahd_flag flags; struct seeprom_config *seep_config; - /* Values to store in the SEQCTL register for pause and unpause */ - uint8_t unpause; - uint8_t pause; - /* Command Queues */ uint16_t qoutfifonext; uint16_t qoutfifonext_valid_tag; @@ -1151,6 +1148,17 @@ struct ahd_softc { uint16_t qinfifo[AHD_SCB_MAX]; uint16_t *qoutfifo; + /* + * Our qfreeze count. The sequencer compares + * this value with its own counter to determine + * whether to allow selections to occur. + */ + uint16_t qfreeze_cnt; + + /* Values to store in the SEQCTL register for pause and unpause */ + uint8_t unpause; + uint8_t pause; + /* Critical Section Data */ struct cs *critical_sections; u_int num_critical_sections; @@ -1197,8 +1205,7 @@ struct ahd_softc { */ bus_dma_tag_t parent_dmat; bus_dma_tag_t shared_data_dmat; - bus_dmamap_t shared_data_dmamap; - dma_addr_t shared_data_busaddr; + struct map_node shared_data_map; /* Information saved through suspend/resume cycles */ struct ahd_suspend_state suspend_state; @@ -1296,9 +1303,9 @@ struct ahd_devinfo { }; /****************************** PCI Structures ********************************/ -#define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ -#define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ -#define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ +#define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/ +#define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */ +#define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */ typedef int (ahd_device_setup_t)(struct ahd_softc *); diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4e8f00df978d..55c44bf54050 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -5203,13 +5203,13 @@ ahd_free(struct ahd_softc *ahd) /* FALLTHROUGH */ case 4: ahd_dmamap_unload(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap); + ahd->shared_data_map.dmamap); /* FALLTHROUGH */ case 3: ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, - ahd->shared_data_dmamap); + ahd->shared_data_map.dmamap); ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap); + ahd->shared_data_map.dmamap); /* FALLTHROUGH */ case 2: ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); @@ -6088,7 +6088,6 @@ static const char *termstat_strings[] = { int ahd_init(struct ahd_softc *ahd) { - uint8_t *base_vaddr; uint8_t *next_vaddr; dma_addr_t next_baddr; size_t driver_data_size; @@ -6178,20 +6177,23 @@ ahd_init(struct ahd_softc *ahd) /* Allocation of driver data */ if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, - (void **)&base_vaddr, - BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { + (void **)&ahd->shared_data_map.vaddr, + BUS_DMA_NOWAIT, + &ahd->shared_data_map.dmamap) != 0) { return (ENOMEM); } ahd->init_level++; /* And permanently map it in */ - ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - base_vaddr, driver_data_size, ahd_dmamap_cb, - &ahd->shared_data_busaddr, /*flags*/0); - ahd->qoutfifo = (uint16_t *)base_vaddr; + ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, + ahd->shared_data_map.vaddr, driver_data_size, + ahd_dmamap_cb, &ahd->shared_data_map.physaddr, + /*flags*/0); + ahd->qoutfifo = (uint16_t *)ahd->shared_data_map.vaddr; next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; - next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); + next_baddr = ahd->shared_data_map.physaddr + + AHD_QOUT_SIZE*sizeof(uint16_t); if ((ahd->features & AHD_TARGETMODE) != 0) { ahd->targetcmds = (struct target_cmd *)next_vaddr; next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); @@ -6212,6 +6214,7 @@ ahd_init(struct ahd_softc *ahd) * specially from the DMA safe memory chunk used for the QOUTFIFO. */ ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; + ahd->next_queued_hscb_map = &ahd->shared_data_map; ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); ahd->init_level++; @@ -6557,12 +6560,13 @@ ahd_chip_init(struct ahd_softc *ahd) /* * The Freeze Count is 0. */ + ahd->qfreeze_cnt = 0; ahd_outw(ahd, QFREEZE_COUNT, 0); /* * Tell the sequencer where it can find our arrays in memory. */ - busaddr = ahd->shared_data_busaddr; + busaddr = ahd->shared_data_map.physaddr; ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); @@ -9651,7 +9655,7 @@ ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) cmd->cmd_valid = 0; ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, + ahd->shared_data_map.dmamap, ahd_targetcmd_offset(ahd, ahd->tqinfifonext), sizeof(struct target_cmd), BUS_DMASYNC_PREREAD); diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h index d80bc5161fb1..2b7ff989f3d1 100644 --- a/drivers/scsi/aic7xxx/aic79xx_inline.h +++ b/drivers/scsi/aic7xxx/aic79xx_inline.h @@ -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/aic79xx_inline.h#51 $ + * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $ * * $FreeBSD$ */ @@ -522,12 +522,21 @@ do { \ static __inline uint16_t ahd_inw(struct ahd_softc *ahd, u_int port) { + /* + * Read high byte first as some registers increment + * or have other side effects when the low byte is + * read. + */ return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); } static __inline void ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) { + /* + * Write low byte first to accomodate registers + * such as PRGMCNT where the order maters. + */ ahd_outb(ahd, port, value & 0xFF); ahd_outb(ahd, port+1, (value >> 8) & 0xFF); } @@ -684,7 +693,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) * Razor #528 */ value = ahd_inb(ahd, offset); - if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0) + if ((ahd->bugs & AHD_PCIX_SCBRAM_RD_BUG) != 0) ahd_inb(ahd, MODE_PTR); return (value); } @@ -727,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) static __inline void ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) { - struct hardware_scb *q_hscb; + struct hardware_scb *q_hscb; + struct map_node *q_hscb_map; uint32_t saved_hscb_busaddr; /* @@ -743,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) * locate the correct SCB by SCB_TAG. */ q_hscb = ahd->next_queued_hscb; + q_hscb_map = ahd->next_queued_hscb_map; saved_hscb_busaddr = q_hscb->hscb_busaddr; memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); q_hscb->hscb_busaddr = saved_hscb_busaddr; @@ -750,7 +761,9 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) /* Now swap HSCB pointers. */ ahd->next_queued_hscb = scb->hscb; + ahd->next_queued_hscb_map = scb->hscb_map; scb->hscb = q_hscb; + scb->hscb_map = q_hscb_map; /* Now define the mapping from tag to SCB in the scbindex */ ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; @@ -824,8 +837,9 @@ static __inline int ahd_intr(struct ahd_softc *ahd); static __inline void ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) { - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, + /*offset*/0, + /*len*/AHD_SCB_MAX * sizeof(uint16_t), op); } static __inline void @@ -834,7 +848,7 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) #ifdef AHD_TARGET_MODE if ((ahd->flags & AHD_TARGETROLE) != 0) { ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, + ahd->shared_data_map.dmamap, ahd_targetcmd_offset(ahd, 0), sizeof(struct target_cmd) * AHD_TMODE_CMDS, op); @@ -854,9 +868,9 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) u_int retval; retval = 0; - ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, - /*offset*/ahd->qoutfifonext, /*len*/2, - BUS_DMASYNC_POSTREAD); + ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, + /*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo), + /*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD); if ((ahd->qoutfifo[ahd->qoutfifonext] & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) retval |= AHD_RUN_QOUTFIFO; @@ -864,7 +878,7 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) if ((ahd->flags & AHD_TARGETROLE) != 0 && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { ahd_dmamap_sync(ahd, ahd->shared_data_dmat, - ahd->shared_data_dmamap, + ahd->shared_data_map.dmamap, ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), /*len*/sizeof(struct target_cmd), BUS_DMASYNC_POSTREAD); |