src/sys/dev/ic/ahcivar.h

154 lines
3.8 KiB
C

/* $OpenBSD: ahcivar.h,v 1.11 2021/05/30 15:05:33 visa Exp $ */
/*
* Copyright (c) 2006 David Gwynne <dlg@openbsd.org>
* Copyright (c) 2010 Conformal Systems LLC <info@conformal.com>
* Copyright (c) 2010 Jonathan Matthew <jonathan@d14n.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/mutex.h>
#include <sys/timeout.h>
#include <dev/ata/atascsi.h>
#include <dev/ata/pmreg.h>
/* change to AHCI_DEBUG for dmesg spam */
#define NO_AHCI_DEBUG
struct ahci_dmamem {
bus_dmamap_t adm_map;
bus_dma_segment_t adm_seg;
size_t adm_size;
caddr_t adm_kva;
};
#define AHCI_DMA_MAP(_adm) ((_adm)->adm_map)
#define AHCI_DMA_DVA(_adm) ((u_int64_t)(_adm)->adm_map->dm_segs[0].ds_addr)
#define AHCI_DMA_KVA(_adm) ((void *)(_adm)->adm_kva)
struct ahci_softc;
struct ahci_port;
struct ahci_ccb {
/* ATA xfer associated with this CCB. Must be 1st struct member. */
struct ata_xfer ccb_xa;
int ccb_slot;
struct ahci_port *ccb_port;
bus_dmamap_t ccb_dmamap;
struct ahci_cmd_hdr *ccb_cmd_hdr;
struct ahci_cmd_table *ccb_cmd_table;
void (*ccb_done)(struct ahci_ccb *);
TAILQ_ENTRY(ahci_ccb) ccb_entry;
};
struct ahci_port {
struct ahci_softc *ap_sc;
bus_space_handle_t ap_ioh;
#ifdef AHCI_COALESCE
int ap_num;
#endif
struct ahci_rfis *ap_rfis;
struct ahci_dmamem *ap_dmamem_rfis;
struct ahci_dmamem *ap_dmamem_cmd_list;
struct ahci_dmamem *ap_dmamem_cmd_table;
volatile u_int32_t ap_active;
volatile u_int32_t ap_active_cnt;
volatile u_int32_t ap_sactive;
volatile u_int32_t ap_pmp_ncq_port;
struct ahci_ccb *ap_ccbs;
TAILQ_HEAD(, ahci_ccb) ap_ccb_free;
TAILQ_HEAD(, ahci_ccb) ap_ccb_pending;
struct mutex ap_ccb_mtx;
struct ahci_ccb *ap_ccb_err;
u_int32_t ap_state;
#define AP_S_NORMAL 0
#define AP_S_PMP_PROBE 1
#define AP_S_PMP_PORT_PROBE 2
#define AP_S_ERROR_RECOVERY 3
#define AP_S_FATAL_ERROR 4
int ap_pmp_ports;
int ap_port;
int ap_pmp_ignore_ifs;
/* For error recovery. */
#ifdef DIAGNOSTIC
int ap_err_busy;
#endif
u_int32_t ap_err_saved_sactive;
u_int32_t ap_err_saved_active;
u_int32_t ap_err_saved_active_cnt;
u_int32_t ap_saved_cmd;
u_int8_t *ap_err_scratch;
#ifdef AHCI_DEBUG
char ap_name[16];
#define PORTNAME(_ap) ((_ap)->ap_name)
#else
#define PORTNAME(_ap) DEVNAME((_ap)->ap_sc)
#endif
};
struct ahci_softc {
struct device sc_dev;
void *sc_ih;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
bus_size_t sc_ios;
bus_dma_tag_t sc_dmat;
int sc_flags;
#define AHCI_F_NO_NCQ (1<<0)
#define AHCI_F_IPMS_PROBE (1<<1) /* IPMS on failed PMP probe */
#define AHCI_F_NO_PMP (1<<2) /* ignore PMP capability */
#define AHCI_F_NO_MSI (1<<3) /* disable MSI */
u_int sc_ncmds;
struct ahci_port *sc_ports[AHCI_MAX_PORTS];
struct atascsi *sc_atascsi;
u_int32_t sc_cap;
#ifdef AHCI_COALESCE
u_int32_t sc_ccc_mask;
u_int32_t sc_ccc_ports;
u_int32_t sc_ccc_ports_cur;
#endif
int (*sc_port_start)(struct ahci_port *, int);
};
#define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
#define ahci_port_start(_p, _f) ((_p)->ap_sc->sc_port_start((_p), (_f)))
int ahci_attach(struct ahci_softc *);
int ahci_detach(struct ahci_softc *, int);
int ahci_activate(struct device *, int);
int ahci_intr(void *);