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 @@ | |||
37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | * POSSIBILITY OF SUCH DAMAGES. | 38 | * POSSIBILITY OF SUCH DAMAGES. |
39 | * | 39 | * |
40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#95 $ | 40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx.h#108 $ |
41 | * | 41 | * |
42 | * $FreeBSD$ | 42 | * $FreeBSD$ |
43 | */ | 43 | */ |
@@ -1062,6 +1062,7 @@ struct ahd_softc { | |||
1062 | struct scb_data scb_data; | 1062 | struct scb_data scb_data; |
1063 | 1063 | ||
1064 | struct hardware_scb *next_queued_hscb; | 1064 | struct hardware_scb *next_queued_hscb; |
1065 | struct map_node *next_queued_hscb_map; | ||
1065 | 1066 | ||
1066 | /* | 1067 | /* |
1067 | * SCBs that have been sent to the controller | 1068 | * SCBs that have been sent to the controller |
@@ -1140,10 +1141,6 @@ struct ahd_softc { | |||
1140 | ahd_flag flags; | 1141 | ahd_flag flags; |
1141 | struct seeprom_config *seep_config; | 1142 | struct seeprom_config *seep_config; |
1142 | 1143 | ||
1143 | /* Values to store in the SEQCTL register for pause and unpause */ | ||
1144 | uint8_t unpause; | ||
1145 | uint8_t pause; | ||
1146 | |||
1147 | /* Command Queues */ | 1144 | /* Command Queues */ |
1148 | uint16_t qoutfifonext; | 1145 | uint16_t qoutfifonext; |
1149 | uint16_t qoutfifonext_valid_tag; | 1146 | uint16_t qoutfifonext_valid_tag; |
@@ -1151,6 +1148,17 @@ struct ahd_softc { | |||
1151 | uint16_t qinfifo[AHD_SCB_MAX]; | 1148 | uint16_t qinfifo[AHD_SCB_MAX]; |
1152 | uint16_t *qoutfifo; | 1149 | uint16_t *qoutfifo; |
1153 | 1150 | ||
1151 | /* | ||
1152 | * Our qfreeze count. The sequencer compares | ||
1153 | * this value with its own counter to determine | ||
1154 | * whether to allow selections to occur. | ||
1155 | */ | ||
1156 | uint16_t qfreeze_cnt; | ||
1157 | |||
1158 | /* Values to store in the SEQCTL register for pause and unpause */ | ||
1159 | uint8_t unpause; | ||
1160 | uint8_t pause; | ||
1161 | |||
1154 | /* Critical Section Data */ | 1162 | /* Critical Section Data */ |
1155 | struct cs *critical_sections; | 1163 | struct cs *critical_sections; |
1156 | u_int num_critical_sections; | 1164 | u_int num_critical_sections; |
@@ -1197,8 +1205,7 @@ struct ahd_softc { | |||
1197 | */ | 1205 | */ |
1198 | bus_dma_tag_t parent_dmat; | 1206 | bus_dma_tag_t parent_dmat; |
1199 | bus_dma_tag_t shared_data_dmat; | 1207 | bus_dma_tag_t shared_data_dmat; |
1200 | bus_dmamap_t shared_data_dmamap; | 1208 | struct map_node shared_data_map; |
1201 | dma_addr_t shared_data_busaddr; | ||
1202 | 1209 | ||
1203 | /* Information saved through suspend/resume cycles */ | 1210 | /* Information saved through suspend/resume cycles */ |
1204 | struct ahd_suspend_state suspend_state; | 1211 | struct ahd_suspend_state suspend_state; |
@@ -1296,9 +1303,9 @@ struct ahd_devinfo { | |||
1296 | }; | 1303 | }; |
1297 | 1304 | ||
1298 | /****************************** PCI Structures ********************************/ | 1305 | /****************************** PCI Structures ********************************/ |
1299 | #define AHD_PCI_IOADDR0 PCIR_MAPS /* I/O BAR*/ | 1306 | #define AHD_PCI_IOADDR0 PCIR_BAR(0) /* I/O BAR*/ |
1300 | #define AHD_PCI_MEMADDR (PCIR_MAPS + 4) /* Memory BAR */ | 1307 | #define AHD_PCI_MEMADDR PCIR_BAR(1) /* Memory BAR */ |
1301 | #define AHD_PCI_IOADDR1 (PCIR_MAPS + 12)/* Second I/O BAR */ | 1308 | #define AHD_PCI_IOADDR1 PCIR_BAR(3) /* Second I/O BAR */ |
1302 | 1309 | ||
1303 | typedef int (ahd_device_setup_t)(struct ahd_softc *); | 1310 | typedef int (ahd_device_setup_t)(struct ahd_softc *); |
1304 | 1311 | ||
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) | |||
5203 | /* FALLTHROUGH */ | 5203 | /* FALLTHROUGH */ |
5204 | case 4: | 5204 | case 4: |
5205 | ahd_dmamap_unload(ahd, ahd->shared_data_dmat, | 5205 | ahd_dmamap_unload(ahd, ahd->shared_data_dmat, |
5206 | ahd->shared_data_dmamap); | 5206 | ahd->shared_data_map.dmamap); |
5207 | /* FALLTHROUGH */ | 5207 | /* FALLTHROUGH */ |
5208 | case 3: | 5208 | case 3: |
5209 | ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, | 5209 | ahd_dmamem_free(ahd, ahd->shared_data_dmat, ahd->qoutfifo, |
5210 | ahd->shared_data_dmamap); | 5210 | ahd->shared_data_map.dmamap); |
5211 | ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, | 5211 | ahd_dmamap_destroy(ahd, ahd->shared_data_dmat, |
5212 | ahd->shared_data_dmamap); | 5212 | ahd->shared_data_map.dmamap); |
5213 | /* FALLTHROUGH */ | 5213 | /* FALLTHROUGH */ |
5214 | case 2: | 5214 | case 2: |
5215 | ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); | 5215 | ahd_dma_tag_destroy(ahd, ahd->shared_data_dmat); |
@@ -6088,7 +6088,6 @@ static const char *termstat_strings[] = { | |||
6088 | int | 6088 | int |
6089 | ahd_init(struct ahd_softc *ahd) | 6089 | ahd_init(struct ahd_softc *ahd) |
6090 | { | 6090 | { |
6091 | uint8_t *base_vaddr; | ||
6092 | uint8_t *next_vaddr; | 6091 | uint8_t *next_vaddr; |
6093 | dma_addr_t next_baddr; | 6092 | dma_addr_t next_baddr; |
6094 | size_t driver_data_size; | 6093 | size_t driver_data_size; |
@@ -6178,20 +6177,23 @@ ahd_init(struct ahd_softc *ahd) | |||
6178 | 6177 | ||
6179 | /* Allocation of driver data */ | 6178 | /* Allocation of driver data */ |
6180 | if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, | 6179 | if (ahd_dmamem_alloc(ahd, ahd->shared_data_dmat, |
6181 | (void **)&base_vaddr, | 6180 | (void **)&ahd->shared_data_map.vaddr, |
6182 | BUS_DMA_NOWAIT, &ahd->shared_data_dmamap) != 0) { | 6181 | BUS_DMA_NOWAIT, |
6182 | &ahd->shared_data_map.dmamap) != 0) { | ||
6183 | return (ENOMEM); | 6183 | return (ENOMEM); |
6184 | } | 6184 | } |
6185 | 6185 | ||
6186 | ahd->init_level++; | 6186 | ahd->init_level++; |
6187 | 6187 | ||
6188 | /* And permanently map it in */ | 6188 | /* And permanently map it in */ |
6189 | ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, | 6189 | ahd_dmamap_load(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, |
6190 | base_vaddr, driver_data_size, ahd_dmamap_cb, | 6190 | ahd->shared_data_map.vaddr, driver_data_size, |
6191 | &ahd->shared_data_busaddr, /*flags*/0); | 6191 | ahd_dmamap_cb, &ahd->shared_data_map.physaddr, |
6192 | ahd->qoutfifo = (uint16_t *)base_vaddr; | 6192 | /*flags*/0); |
6193 | ahd->qoutfifo = (uint16_t *)ahd->shared_data_map.vaddr; | ||
6193 | next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; | 6194 | next_vaddr = (uint8_t *)&ahd->qoutfifo[AHD_QOUT_SIZE]; |
6194 | next_baddr = ahd->shared_data_busaddr + AHD_QOUT_SIZE*sizeof(uint16_t); | 6195 | next_baddr = ahd->shared_data_map.physaddr |
6196 | + AHD_QOUT_SIZE*sizeof(uint16_t); | ||
6195 | if ((ahd->features & AHD_TARGETMODE) != 0) { | 6197 | if ((ahd->features & AHD_TARGETMODE) != 0) { |
6196 | ahd->targetcmds = (struct target_cmd *)next_vaddr; | 6198 | ahd->targetcmds = (struct target_cmd *)next_vaddr; |
6197 | next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); | 6199 | next_vaddr += AHD_TMODE_CMDS * sizeof(struct target_cmd); |
@@ -6212,6 +6214,7 @@ ahd_init(struct ahd_softc *ahd) | |||
6212 | * specially from the DMA safe memory chunk used for the QOUTFIFO. | 6214 | * specially from the DMA safe memory chunk used for the QOUTFIFO. |
6213 | */ | 6215 | */ |
6214 | ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; | 6216 | ahd->next_queued_hscb = (struct hardware_scb *)next_vaddr; |
6217 | ahd->next_queued_hscb_map = &ahd->shared_data_map; | ||
6215 | ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); | 6218 | ahd->next_queued_hscb->hscb_busaddr = ahd_htole32(next_baddr); |
6216 | 6219 | ||
6217 | ahd->init_level++; | 6220 | ahd->init_level++; |
@@ -6557,12 +6560,13 @@ ahd_chip_init(struct ahd_softc *ahd) | |||
6557 | /* | 6560 | /* |
6558 | * The Freeze Count is 0. | 6561 | * The Freeze Count is 0. |
6559 | */ | 6562 | */ |
6563 | ahd->qfreeze_cnt = 0; | ||
6560 | ahd_outw(ahd, QFREEZE_COUNT, 0); | 6564 | ahd_outw(ahd, QFREEZE_COUNT, 0); |
6561 | 6565 | ||
6562 | /* | 6566 | /* |
6563 | * Tell the sequencer where it can find our arrays in memory. | 6567 | * Tell the sequencer where it can find our arrays in memory. |
6564 | */ | 6568 | */ |
6565 | busaddr = ahd->shared_data_busaddr; | 6569 | busaddr = ahd->shared_data_map.physaddr; |
6566 | ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); | 6570 | ahd_outb(ahd, SHARED_DATA_ADDR, busaddr & 0xFF); |
6567 | ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); | 6571 | ahd_outb(ahd, SHARED_DATA_ADDR + 1, (busaddr >> 8) & 0xFF); |
6568 | ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); | 6572 | ahd_outb(ahd, SHARED_DATA_ADDR + 2, (busaddr >> 16) & 0xFF); |
@@ -9651,7 +9655,7 @@ ahd_run_tqinfifo(struct ahd_softc *ahd, int paused) | |||
9651 | 9655 | ||
9652 | cmd->cmd_valid = 0; | 9656 | cmd->cmd_valid = 0; |
9653 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, | 9657 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, |
9654 | ahd->shared_data_dmamap, | 9658 | ahd->shared_data_map.dmamap, |
9655 | ahd_targetcmd_offset(ahd, ahd->tqinfifonext), | 9659 | ahd_targetcmd_offset(ahd, ahd->tqinfifonext), |
9656 | sizeof(struct target_cmd), | 9660 | sizeof(struct target_cmd), |
9657 | BUS_DMASYNC_PREREAD); | 9661 | 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 @@ | |||
37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 37 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | * POSSIBILITY OF SUCH DAMAGES. | 38 | * POSSIBILITY OF SUCH DAMAGES. |
39 | * | 39 | * |
40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#51 $ | 40 | * $Id: //depot/aic7xxx/aic7xxx/aic79xx_inline.h#58 $ |
41 | * | 41 | * |
42 | * $FreeBSD$ | 42 | * $FreeBSD$ |
43 | */ | 43 | */ |
@@ -522,12 +522,21 @@ do { \ | |||
522 | static __inline uint16_t | 522 | static __inline uint16_t |
523 | ahd_inw(struct ahd_softc *ahd, u_int port) | 523 | ahd_inw(struct ahd_softc *ahd, u_int port) |
524 | { | 524 | { |
525 | /* | ||
526 | * Read high byte first as some registers increment | ||
527 | * or have other side effects when the low byte is | ||
528 | * read. | ||
529 | */ | ||
525 | return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); | 530 | return ((ahd_inb(ahd, port+1) << 8) | ahd_inb(ahd, port)); |
526 | } | 531 | } |
527 | 532 | ||
528 | static __inline void | 533 | static __inline void |
529 | ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) | 534 | ahd_outw(struct ahd_softc *ahd, u_int port, u_int value) |
530 | { | 535 | { |
536 | /* | ||
537 | * Write low byte first to accomodate registers | ||
538 | * such as PRGMCNT where the order maters. | ||
539 | */ | ||
531 | ahd_outb(ahd, port, value & 0xFF); | 540 | ahd_outb(ahd, port, value & 0xFF); |
532 | ahd_outb(ahd, port+1, (value >> 8) & 0xFF); | 541 | ahd_outb(ahd, port+1, (value >> 8) & 0xFF); |
533 | } | 542 | } |
@@ -684,7 +693,7 @@ ahd_inb_scbram(struct ahd_softc *ahd, u_int offset) | |||
684 | * Razor #528 | 693 | * Razor #528 |
685 | */ | 694 | */ |
686 | value = ahd_inb(ahd, offset); | 695 | value = ahd_inb(ahd, offset); |
687 | if ((ahd->flags & AHD_PCIX_SCBRAM_RD_BUG) != 0) | 696 | if ((ahd->bugs & AHD_PCIX_SCBRAM_RD_BUG) != 0) |
688 | ahd_inb(ahd, MODE_PTR); | 697 | ahd_inb(ahd, MODE_PTR); |
689 | return (value); | 698 | return (value); |
690 | } | 699 | } |
@@ -727,7 +736,8 @@ ahd_lookup_scb(struct ahd_softc *ahd, u_int tag) | |||
727 | static __inline void | 736 | static __inline void |
728 | ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) | 737 | ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) |
729 | { | 738 | { |
730 | struct hardware_scb *q_hscb; | 739 | struct hardware_scb *q_hscb; |
740 | struct map_node *q_hscb_map; | ||
731 | uint32_t saved_hscb_busaddr; | 741 | uint32_t saved_hscb_busaddr; |
732 | 742 | ||
733 | /* | 743 | /* |
@@ -743,6 +753,7 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) | |||
743 | * locate the correct SCB by SCB_TAG. | 753 | * locate the correct SCB by SCB_TAG. |
744 | */ | 754 | */ |
745 | q_hscb = ahd->next_queued_hscb; | 755 | q_hscb = ahd->next_queued_hscb; |
756 | q_hscb_map = ahd->next_queued_hscb_map; | ||
746 | saved_hscb_busaddr = q_hscb->hscb_busaddr; | 757 | saved_hscb_busaddr = q_hscb->hscb_busaddr; |
747 | memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); | 758 | memcpy(q_hscb, scb->hscb, sizeof(*scb->hscb)); |
748 | q_hscb->hscb_busaddr = saved_hscb_busaddr; | 759 | q_hscb->hscb_busaddr = saved_hscb_busaddr; |
@@ -750,7 +761,9 @@ ahd_swap_with_next_hscb(struct ahd_softc *ahd, struct scb *scb) | |||
750 | 761 | ||
751 | /* Now swap HSCB pointers. */ | 762 | /* Now swap HSCB pointers. */ |
752 | ahd->next_queued_hscb = scb->hscb; | 763 | ahd->next_queued_hscb = scb->hscb; |
764 | ahd->next_queued_hscb_map = scb->hscb_map; | ||
753 | scb->hscb = q_hscb; | 765 | scb->hscb = q_hscb; |
766 | scb->hscb_map = q_hscb_map; | ||
754 | 767 | ||
755 | /* Now define the mapping from tag to SCB in the scbindex */ | 768 | /* Now define the mapping from tag to SCB in the scbindex */ |
756 | ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; | 769 | ahd->scb_data.scbindex[SCB_GET_TAG(scb)] = scb; |
@@ -824,8 +837,9 @@ static __inline int ahd_intr(struct ahd_softc *ahd); | |||
824 | static __inline void | 837 | static __inline void |
825 | ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) | 838 | ahd_sync_qoutfifo(struct ahd_softc *ahd, int op) |
826 | { | 839 | { |
827 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, | 840 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, |
828 | /*offset*/0, /*len*/AHC_SCB_MAX * sizeof(uint16_t), op); | 841 | /*offset*/0, |
842 | /*len*/AHD_SCB_MAX * sizeof(uint16_t), op); | ||
829 | } | 843 | } |
830 | 844 | ||
831 | static __inline void | 845 | static __inline void |
@@ -834,7 +848,7 @@ ahd_sync_tqinfifo(struct ahd_softc *ahd, int op) | |||
834 | #ifdef AHD_TARGET_MODE | 848 | #ifdef AHD_TARGET_MODE |
835 | if ((ahd->flags & AHD_TARGETROLE) != 0) { | 849 | if ((ahd->flags & AHD_TARGETROLE) != 0) { |
836 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, | 850 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, |
837 | ahd->shared_data_dmamap, | 851 | ahd->shared_data_map.dmamap, |
838 | ahd_targetcmd_offset(ahd, 0), | 852 | ahd_targetcmd_offset(ahd, 0), |
839 | sizeof(struct target_cmd) * AHD_TMODE_CMDS, | 853 | sizeof(struct target_cmd) * AHD_TMODE_CMDS, |
840 | op); | 854 | op); |
@@ -854,9 +868,9 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) | |||
854 | u_int retval; | 868 | u_int retval; |
855 | 869 | ||
856 | retval = 0; | 870 | retval = 0; |
857 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_dmamap, | 871 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, ahd->shared_data_map.dmamap, |
858 | /*offset*/ahd->qoutfifonext, /*len*/2, | 872 | /*offset*/ahd->qoutfifonext * sizeof(*ahd->qoutfifo), |
859 | BUS_DMASYNC_POSTREAD); | 873 | /*len*/sizeof(*ahd->qoutfifo), BUS_DMASYNC_POSTREAD); |
860 | if ((ahd->qoutfifo[ahd->qoutfifonext] | 874 | if ((ahd->qoutfifo[ahd->qoutfifonext] |
861 | & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) | 875 | & QOUTFIFO_ENTRY_VALID_LE) == ahd->qoutfifonext_valid_tag) |
862 | retval |= AHD_RUN_QOUTFIFO; | 876 | retval |= AHD_RUN_QOUTFIFO; |
@@ -864,7 +878,7 @@ ahd_check_cmdcmpltqueues(struct ahd_softc *ahd) | |||
864 | if ((ahd->flags & AHD_TARGETROLE) != 0 | 878 | if ((ahd->flags & AHD_TARGETROLE) != 0 |
865 | && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { | 879 | && (ahd->flags & AHD_TQINFIFO_BLOCKED) == 0) { |
866 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, | 880 | ahd_dmamap_sync(ahd, ahd->shared_data_dmat, |
867 | ahd->shared_data_dmamap, | 881 | ahd->shared_data_map.dmamap, |
868 | ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), | 882 | ahd_targetcmd_offset(ahd, ahd->tqinfifofnext), |
869 | /*len*/sizeof(struct target_cmd), | 883 | /*len*/sizeof(struct target_cmd), |
870 | BUS_DMASYNC_POSTREAD); | 884 | BUS_DMASYNC_POSTREAD); |