1 /* $OpenBSD: ahcivar.h,v 1.11 2021/05/30 15:05:33 visa Exp $ */ 2 3 /* 4 * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> 5 * Copyright (c) 2010 Conformal Systems LLC <info@conformal.com> 6 * Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org> 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/mutex.h> 22 #include <sys/timeout.h> 23 #include <dev/ata/atascsi.h> 24 #include <dev/ata/pmreg.h> 25 26 /* change to AHCI_DEBUG for dmesg spam */ 27 #define NO_AHCI_DEBUG 28 29 struct ahci_dmamem { 30 bus_dmamap_t adm_map; 31 bus_dma_segment_t adm_seg; 32 size_t adm_size; 33 caddr_t adm_kva; 34 }; 35 #define AHCI_DMA_MAP(_adm) ((_adm)->adm_map) 36 #define AHCI_DMA_DVA(_adm) ((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr) 37 #define AHCI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva) 38 39 struct ahci_softc; 40 struct ahci_port; 41 42 struct ahci_ccb { 43 /* ATA xfer associated with this CCB. Must be 1st struct member. */ 44 struct ata_xfer ccb_xa; 45 46 int ccb_slot; 47 struct ahci_port *ccb_port; 48 49 bus_dmamap_t ccb_dmamap; 50 struct ahci_cmd_hdr *ccb_cmd_hdr; 51 struct ahci_cmd_table *ccb_cmd_table; 52 53 void (*ccb_done)(struct ahci_ccb *); 54 55 TAILQ_ENTRY(ahci_ccb) ccb_entry; 56 }; 57 58 struct ahci_port { 59 struct ahci_softc *ap_sc; 60 bus_space_handle_t ap_ioh; 61 62 #ifdef AHCI_COALESCE 63 int ap_num; 64 #endif 65 66 struct ahci_rfis *ap_rfis; 67 struct ahci_dmamem *ap_dmamem_rfis; 68 69 struct ahci_dmamem *ap_dmamem_cmd_list; 70 struct ahci_dmamem *ap_dmamem_cmd_table; 71 72 volatile u_int32_t ap_active; 73 volatile u_int32_t ap_active_cnt; 74 volatile u_int32_t ap_sactive; 75 volatile u_int32_t ap_pmp_ncq_port; 76 struct ahci_ccb *ap_ccbs; 77 78 TAILQ_HEAD(, ahci_ccb) ap_ccb_free; 79 TAILQ_HEAD(, ahci_ccb) ap_ccb_pending; 80 struct mutex ap_ccb_mtx; 81 struct ahci_ccb *ap_ccb_err; 82 83 u_int32_t ap_state; 84 #define AP_S_NORMAL 0 85 #define AP_S_PMP_PROBE 1 86 #define AP_S_PMP_PORT_PROBE 2 87 #define AP_S_ERROR_RECOVERY 3 88 #define AP_S_FATAL_ERROR 4 89 90 int ap_pmp_ports; 91 int ap_port; 92 int ap_pmp_ignore_ifs; 93 94 /* For error recovery. */ 95 #ifdef DIAGNOSTIC 96 int ap_err_busy; 97 #endif 98 u_int32_t ap_err_saved_sactive; 99 u_int32_t ap_err_saved_active; 100 u_int32_t ap_err_saved_active_cnt; 101 u_int32_t ap_saved_cmd; 102 103 u_int8_t *ap_err_scratch; 104 105 #ifdef AHCI_DEBUG 106 char ap_name[16]; 107 #define PORTNAME(_ap) ((_ap)->ap_name) 108 #else 109 #define PORTNAME(_ap) DEVNAME((_ap)->ap_sc) 110 #endif 111 }; 112 113 struct ahci_softc { 114 struct device sc_dev; 115 116 void *sc_ih; 117 118 bus_space_tag_t sc_iot; 119 bus_space_handle_t sc_ioh; 120 bus_size_t sc_ios; 121 bus_dma_tag_t sc_dmat; 122 123 int sc_flags; 124 #define AHCI_F_NO_NCQ (1<<0) 125 #define AHCI_F_IPMS_PROBE (1<<1) /* IPMS on failed PMP probe */ 126 #define AHCI_F_NO_PMP (1<<2) /* ignore PMP capability */ 127 #define AHCI_F_NO_MSI (1<<3) /* disable MSI */ 128 129 u_int sc_ncmds; 130 131 struct ahci_port *sc_ports[AHCI_MAX_PORTS]; 132 133 struct atascsi *sc_atascsi; 134 135 u_int32_t sc_cap; 136 137 #ifdef AHCI_COALESCE 138 u_int32_t sc_ccc_mask; 139 u_int32_t sc_ccc_ports; 140 u_int32_t sc_ccc_ports_cur; 141 #endif 142 143 int (*sc_port_start)(struct ahci_port *, int); 144 }; 145 146 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 147 #define ahci_port_start(_p, _f) ((_p)->ap_sc->sc_port_start((_p), (_f))) 148 149 int ahci_attach(struct ahci_softc *); 150 int ahci_detach(struct ahci_softc *, int); 151 int ahci_activate(struct device *, int); 152 153 int ahci_intr(void *); 154