1*9ced64eaSvisa /* $OpenBSD: ahcivar.h,v 1.11 2021/05/30 15:05:33 visa Exp $ */ 27acdc34dSpatrick 37acdc34dSpatrick /* 47acdc34dSpatrick * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> 57acdc34dSpatrick * Copyright (c) 2010 Conformal Systems LLC <info@conformal.com> 67acdc34dSpatrick * Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org> 77acdc34dSpatrick * 87acdc34dSpatrick * Permission to use, copy, modify, and distribute this software for any 97acdc34dSpatrick * purpose with or without fee is hereby granted, provided that the above 107acdc34dSpatrick * copyright notice and this permission notice appear in all copies. 117acdc34dSpatrick * 127acdc34dSpatrick * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 137acdc34dSpatrick * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 147acdc34dSpatrick * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 157acdc34dSpatrick * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 167acdc34dSpatrick * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 177acdc34dSpatrick * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 187acdc34dSpatrick * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 197acdc34dSpatrick */ 207acdc34dSpatrick 21*9ced64eaSvisa #include <sys/mutex.h> 227acdc34dSpatrick #include <sys/timeout.h> 237acdc34dSpatrick #include <dev/ata/atascsi.h> 247acdc34dSpatrick #include <dev/ata/pmreg.h> 257acdc34dSpatrick 267acdc34dSpatrick /* change to AHCI_DEBUG for dmesg spam */ 277acdc34dSpatrick #define NO_AHCI_DEBUG 287acdc34dSpatrick 297acdc34dSpatrick struct ahci_dmamem { 307acdc34dSpatrick bus_dmamap_t adm_map; 317acdc34dSpatrick bus_dma_segment_t adm_seg; 327acdc34dSpatrick size_t adm_size; 337acdc34dSpatrick caddr_t adm_kva; 347acdc34dSpatrick }; 357acdc34dSpatrick #define AHCI_DMA_MAP(_adm) ((_adm)->adm_map) 3668856203Sdlg #define AHCI_DMA_DVA(_adm) ((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr) 377acdc34dSpatrick #define AHCI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva) 387acdc34dSpatrick 397acdc34dSpatrick struct ahci_softc; 407acdc34dSpatrick struct ahci_port; 417acdc34dSpatrick 427acdc34dSpatrick struct ahci_ccb { 437acdc34dSpatrick /* ATA xfer associated with this CCB. Must be 1st struct member. */ 447acdc34dSpatrick struct ata_xfer ccb_xa; 457acdc34dSpatrick 467acdc34dSpatrick int ccb_slot; 477acdc34dSpatrick struct ahci_port *ccb_port; 487acdc34dSpatrick 497acdc34dSpatrick bus_dmamap_t ccb_dmamap; 507acdc34dSpatrick struct ahci_cmd_hdr *ccb_cmd_hdr; 517acdc34dSpatrick struct ahci_cmd_table *ccb_cmd_table; 527acdc34dSpatrick 537acdc34dSpatrick void (*ccb_done)(struct ahci_ccb *); 547acdc34dSpatrick 557acdc34dSpatrick TAILQ_ENTRY(ahci_ccb) ccb_entry; 567acdc34dSpatrick }; 577acdc34dSpatrick 587acdc34dSpatrick struct ahci_port { 597acdc34dSpatrick struct ahci_softc *ap_sc; 607acdc34dSpatrick bus_space_handle_t ap_ioh; 617acdc34dSpatrick 627acdc34dSpatrick #ifdef AHCI_COALESCE 637acdc34dSpatrick int ap_num; 647acdc34dSpatrick #endif 657acdc34dSpatrick 667acdc34dSpatrick struct ahci_rfis *ap_rfis; 677acdc34dSpatrick struct ahci_dmamem *ap_dmamem_rfis; 687acdc34dSpatrick 697acdc34dSpatrick struct ahci_dmamem *ap_dmamem_cmd_list; 707acdc34dSpatrick struct ahci_dmamem *ap_dmamem_cmd_table; 717acdc34dSpatrick 727acdc34dSpatrick volatile u_int32_t ap_active; 737acdc34dSpatrick volatile u_int32_t ap_active_cnt; 747acdc34dSpatrick volatile u_int32_t ap_sactive; 757acdc34dSpatrick volatile u_int32_t ap_pmp_ncq_port; 767acdc34dSpatrick struct ahci_ccb *ap_ccbs; 777acdc34dSpatrick 787acdc34dSpatrick TAILQ_HEAD(, ahci_ccb) ap_ccb_free; 797acdc34dSpatrick TAILQ_HEAD(, ahci_ccb) ap_ccb_pending; 807acdc34dSpatrick struct mutex ap_ccb_mtx; 817acdc34dSpatrick struct ahci_ccb *ap_ccb_err; 827acdc34dSpatrick 837acdc34dSpatrick u_int32_t ap_state; 847acdc34dSpatrick #define AP_S_NORMAL 0 857acdc34dSpatrick #define AP_S_PMP_PROBE 1 867acdc34dSpatrick #define AP_S_PMP_PORT_PROBE 2 877acdc34dSpatrick #define AP_S_ERROR_RECOVERY 3 887acdc34dSpatrick #define AP_S_FATAL_ERROR 4 897acdc34dSpatrick 907acdc34dSpatrick int ap_pmp_ports; 917acdc34dSpatrick int ap_port; 927acdc34dSpatrick int ap_pmp_ignore_ifs; 937acdc34dSpatrick 947acdc34dSpatrick /* For error recovery. */ 957acdc34dSpatrick #ifdef DIAGNOSTIC 967acdc34dSpatrick int ap_err_busy; 977acdc34dSpatrick #endif 987acdc34dSpatrick u_int32_t ap_err_saved_sactive; 997acdc34dSpatrick u_int32_t ap_err_saved_active; 1007acdc34dSpatrick u_int32_t ap_err_saved_active_cnt; 10196739e86Sjmatthew u_int32_t ap_saved_cmd; 1027acdc34dSpatrick 1037acdc34dSpatrick u_int8_t *ap_err_scratch; 1047acdc34dSpatrick 1057acdc34dSpatrick #ifdef AHCI_DEBUG 1067acdc34dSpatrick char ap_name[16]; 1077acdc34dSpatrick #define PORTNAME(_ap) ((_ap)->ap_name) 1087acdc34dSpatrick #else 1097acdc34dSpatrick #define PORTNAME(_ap) DEVNAME((_ap)->ap_sc) 1107acdc34dSpatrick #endif 1117acdc34dSpatrick }; 1127acdc34dSpatrick 1137acdc34dSpatrick struct ahci_softc { 1147acdc34dSpatrick struct device sc_dev; 1157acdc34dSpatrick 1167acdc34dSpatrick void *sc_ih; 1177acdc34dSpatrick 1187acdc34dSpatrick bus_space_tag_t sc_iot; 1197acdc34dSpatrick bus_space_handle_t sc_ioh; 1207acdc34dSpatrick bus_size_t sc_ios; 1217acdc34dSpatrick bus_dma_tag_t sc_dmat; 1227acdc34dSpatrick 1237acdc34dSpatrick int sc_flags; 1247acdc34dSpatrick #define AHCI_F_NO_NCQ (1<<0) 1257acdc34dSpatrick #define AHCI_F_IPMS_PROBE (1<<1) /* IPMS on failed PMP probe */ 1267acdc34dSpatrick #define AHCI_F_NO_PMP (1<<2) /* ignore PMP capability */ 12751a91e86Sgilles #define AHCI_F_NO_MSI (1<<3) /* disable MSI */ 1287acdc34dSpatrick 1297acdc34dSpatrick u_int sc_ncmds; 1307acdc34dSpatrick 1317acdc34dSpatrick struct ahci_port *sc_ports[AHCI_MAX_PORTS]; 1327acdc34dSpatrick 1337acdc34dSpatrick struct atascsi *sc_atascsi; 1347acdc34dSpatrick 1357acdc34dSpatrick u_int32_t sc_cap; 1367acdc34dSpatrick 1377acdc34dSpatrick #ifdef AHCI_COALESCE 1387acdc34dSpatrick u_int32_t sc_ccc_mask; 1397acdc34dSpatrick u_int32_t sc_ccc_ports; 1407acdc34dSpatrick u_int32_t sc_ccc_ports_cur; 1417acdc34dSpatrick #endif 14293c0f120Sjsg 14393c0f120Sjsg int (*sc_port_start)(struct ahci_port *, int); 1447acdc34dSpatrick }; 1457acdc34dSpatrick 1467acdc34dSpatrick #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 14793c0f120Sjsg #define ahci_port_start(_p, _f) ((_p)->ap_sc->sc_port_start((_p), (_f))) 1487acdc34dSpatrick 1497acdc34dSpatrick int ahci_attach(struct ahci_softc *); 1507acdc34dSpatrick int ahci_detach(struct ahci_softc *, int); 1517acdc34dSpatrick int ahci_activate(struct device *, int); 1527acdc34dSpatrick 1537acdc34dSpatrick int ahci_intr(void *); 154