1 /* $OpenBSD: ahcivar.h,v 1.9 2014/12/03 04:33:06 jsg 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/timeout.h> 22 #include <dev/ata/atascsi.h> 23 #include <dev/ata/pmreg.h> 24 25 /* change to AHCI_DEBUG for dmesg spam */ 26 #define NO_AHCI_DEBUG 27 28 struct ahci_dmamem { 29 bus_dmamap_t adm_map; 30 bus_dma_segment_t adm_seg; 31 size_t adm_size; 32 caddr_t adm_kva; 33 }; 34 #define AHCI_DMA_MAP(_adm) ((_adm)->adm_map) 35 #define AHCI_DMA_DVA(_adm) ((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr) 36 #define AHCI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva) 37 38 struct ahci_softc; 39 struct ahci_port; 40 41 struct ahci_ccb { 42 /* ATA xfer associated with this CCB. Must be 1st struct member. */ 43 struct ata_xfer ccb_xa; 44 45 int ccb_slot; 46 struct ahci_port *ccb_port; 47 48 bus_dmamap_t ccb_dmamap; 49 struct ahci_cmd_hdr *ccb_cmd_hdr; 50 struct ahci_cmd_table *ccb_cmd_table; 51 52 void (*ccb_done)(struct ahci_ccb *); 53 54 TAILQ_ENTRY(ahci_ccb) ccb_entry; 55 }; 56 57 struct ahci_port { 58 struct ahci_softc *ap_sc; 59 bus_space_handle_t ap_ioh; 60 61 #ifdef AHCI_COALESCE 62 int ap_num; 63 #endif 64 65 struct ahci_rfis *ap_rfis; 66 struct ahci_dmamem *ap_dmamem_rfis; 67 68 struct ahci_dmamem *ap_dmamem_cmd_list; 69 struct ahci_dmamem *ap_dmamem_cmd_table; 70 71 volatile u_int32_t ap_active; 72 volatile u_int32_t ap_active_cnt; 73 volatile u_int32_t ap_sactive; 74 volatile u_int32_t ap_pmp_ncq_port; 75 struct ahci_ccb *ap_ccbs; 76 77 TAILQ_HEAD(, ahci_ccb) ap_ccb_free; 78 TAILQ_HEAD(, ahci_ccb) ap_ccb_pending; 79 struct mutex ap_ccb_mtx; 80 struct ahci_ccb *ap_ccb_err; 81 82 u_int32_t ap_state; 83 #define AP_S_NORMAL 0 84 #define AP_S_PMP_PROBE 1 85 #define AP_S_PMP_PORT_PROBE 2 86 #define AP_S_ERROR_RECOVERY 3 87 #define AP_S_FATAL_ERROR 4 88 89 int ap_pmp_ports; 90 int ap_port; 91 int ap_pmp_ignore_ifs; 92 93 /* For error recovery. */ 94 #ifdef DIAGNOSTIC 95 int ap_err_busy; 96 #endif 97 u_int32_t ap_err_saved_sactive; 98 u_int32_t ap_err_saved_active; 99 u_int32_t ap_err_saved_active_cnt; 100 101 u_int8_t *ap_err_scratch; 102 103 #ifdef AHCI_DEBUG 104 char ap_name[16]; 105 #define PORTNAME(_ap) ((_ap)->ap_name) 106 #else 107 #define PORTNAME(_ap) DEVNAME((_ap)->ap_sc) 108 #endif 109 }; 110 111 struct ahci_softc { 112 struct device sc_dev; 113 114 void *sc_ih; 115 116 bus_space_tag_t sc_iot; 117 bus_space_handle_t sc_ioh; 118 bus_size_t sc_ios; 119 bus_dma_tag_t sc_dmat; 120 121 int sc_flags; 122 #define AHCI_F_NO_NCQ (1<<0) 123 #define AHCI_F_IPMS_PROBE (1<<1) /* IPMS on failed PMP probe */ 124 #define AHCI_F_NO_PMP (1<<2) /* ignore PMP capability */ 125 #define AHCI_F_NO_MSI (1<<3) /* disable MSI */ 126 127 u_int sc_ncmds; 128 129 struct ahci_port *sc_ports[AHCI_MAX_PORTS]; 130 131 struct atascsi *sc_atascsi; 132 133 u_int32_t sc_cap; 134 135 #ifdef AHCI_COALESCE 136 u_int32_t sc_ccc_mask; 137 u_int32_t sc_ccc_ports; 138 u_int32_t sc_ccc_ports_cur; 139 #endif 140 141 int (*sc_port_start)(struct ahci_port *, int); 142 }; 143 144 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 145 #define ahci_port_start(_p, _f) ((_p)->ap_sc->sc_port_start((_p), (_f))) 146 147 int ahci_attach(struct ahci_softc *); 148 int ahci_detach(struct ahci_softc *, int); 149 int ahci_activate(struct device *, int); 150 151 int ahci_intr(void *); 152