1db57feb7SJonathan Lemon /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3718cf2ccSPedro F. Giffuni * 4ee7eb00eSJonathan Lemon * Copyright (c) 1999,2000 Jonathan Lemon 5db57feb7SJonathan Lemon * All rights reserved. 6db57feb7SJonathan Lemon * 7db57feb7SJonathan Lemon * Redistribution and use in source and binary forms, with or without 8db57feb7SJonathan Lemon * modification, are permitted provided that the following conditions 9db57feb7SJonathan Lemon * are met: 10db57feb7SJonathan Lemon * 1. Redistributions of source code must retain the above copyright 11db57feb7SJonathan Lemon * notice, this list of conditions and the following disclaimer. 12db57feb7SJonathan Lemon * 2. Redistributions in binary form must reproduce the above copyright 13db57feb7SJonathan Lemon * notice, this list of conditions and the following disclaimer in the 14db57feb7SJonathan Lemon * documentation and/or other materials provided with the distribution. 15db57feb7SJonathan Lemon * 16db57feb7SJonathan Lemon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17db57feb7SJonathan Lemon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18db57feb7SJonathan Lemon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19db57feb7SJonathan Lemon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20db57feb7SJonathan Lemon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21db57feb7SJonathan Lemon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22db57feb7SJonathan Lemon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23db57feb7SJonathan Lemon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24db57feb7SJonathan Lemon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25db57feb7SJonathan Lemon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26db57feb7SJonathan Lemon * SUCH DAMAGE. 27db57feb7SJonathan Lemon */ 28db57feb7SJonathan Lemon 29db57feb7SJonathan Lemon /* 30db57feb7SJonathan Lemon * software structures for the Compaq RAID controller 31db57feb7SJonathan Lemon */ 32db57feb7SJonathan Lemon 33db57feb7SJonathan Lemon #ifndef _IDAVAR_H 34db57feb7SJonathan Lemon #define _IDAVAR_H 35db57feb7SJonathan Lemon 36ee7eb00eSJonathan Lemon #define ida_inb(ida, port) \ 376b5b57aeSJohn Baldwin bus_read_1((ida)->regs, port) 38ee7eb00eSJonathan Lemon #define ida_inw(ida, port) \ 396b5b57aeSJohn Baldwin bus_read_2((ida)->regs, port) 40ee7eb00eSJonathan Lemon #define ida_inl(ida, port) \ 416b5b57aeSJohn Baldwin bus_read_4((ida)->regs, port) 42ee7eb00eSJonathan Lemon 43ee7eb00eSJonathan Lemon #define ida_outb(ida, port, val) \ 446b5b57aeSJohn Baldwin bus_write_1((ida)->regs, port, val) 45ee7eb00eSJonathan Lemon #define ida_outw(ida, port, val) \ 466b5b57aeSJohn Baldwin bus_write_2((ida)->regs, port, val) 47ee7eb00eSJonathan Lemon #define ida_outl(ida, port, val) \ 486b5b57aeSJohn Baldwin bus_write_4((ida)->regs, port, val) 49ee7eb00eSJonathan Lemon 50db57feb7SJonathan Lemon struct ida_hdr { 51db57feb7SJonathan Lemon u_int8_t drive; /* logical drive */ 52db57feb7SJonathan Lemon u_int8_t priority; /* block priority */ 53db57feb7SJonathan Lemon u_int16_t size; /* size of request, in words */ 54db57feb7SJonathan Lemon }; 55db57feb7SJonathan Lemon 56db57feb7SJonathan Lemon struct ida_req { 57db57feb7SJonathan Lemon u_int16_t next; /* offset of next request */ 58db57feb7SJonathan Lemon u_int8_t command; /* command */ 59db57feb7SJonathan Lemon u_int8_t error; /* return error code */ 60db57feb7SJonathan Lemon u_int32_t blkno; /* block number */ 61db57feb7SJonathan Lemon u_int16_t bcount; /* block count */ 62db57feb7SJonathan Lemon u_int8_t sgcount; /* number of scatter/gather entries */ 63db57feb7SJonathan Lemon u_int8_t spare; /* reserved */ 64db57feb7SJonathan Lemon }; 65db57feb7SJonathan Lemon 66db57feb7SJonathan Lemon struct ida_sgb { 67db57feb7SJonathan Lemon u_int32_t length; /* length of S/G segment */ 68db57feb7SJonathan Lemon u_int32_t addr; /* physical address of block */ 69db57feb7SJonathan Lemon }; 70db57feb7SJonathan Lemon 71db57feb7SJonathan Lemon #define IDA_NSEG 32 /* maximum number of segments */ 72db57feb7SJonathan Lemon 73db57feb7SJonathan Lemon /* 74db57feb7SJonathan Lemon * right now, this structure totals 276 bytes. 75db57feb7SJonathan Lemon */ 76db57feb7SJonathan Lemon struct ida_hardware_qcb { 77db57feb7SJonathan Lemon struct ida_hdr hdr; /* 4 */ 78db57feb7SJonathan Lemon struct ida_req req; /* 12 */ 79db57feb7SJonathan Lemon struct ida_sgb seg[IDA_NSEG]; /* 256 */ 80db57feb7SJonathan Lemon struct ida_qcb *qcb; /* 4 - qcb backpointer */ 81db57feb7SJonathan Lemon }; 82db57feb7SJonathan Lemon 83db57feb7SJonathan Lemon typedef enum { 84db57feb7SJonathan Lemon QCB_FREE = 0x0000, 85db57feb7SJonathan Lemon QCB_ACTIVE = 0x0001, /* waiting for completion */ 866b5b57aeSJohn Baldwin QCB_TIMEDOUT = 0x0002, 87db57feb7SJonathan Lemon } qcb_state; 88db57feb7SJonathan Lemon 89db57feb7SJonathan Lemon #define DMA_DATA_IN 0x0001 90db57feb7SJonathan Lemon #define DMA_DATA_OUT 0x0002 91db57feb7SJonathan Lemon #define IDA_COMMAND 0x0004 92db57feb7SJonathan Lemon #define DMA_DATA_TRANSFER (DMA_DATA_IN | DMA_DATA_OUT) 93db57feb7SJonathan Lemon 94db57feb7SJonathan Lemon #define IDA_QCB_MAX 256 95db57feb7SJonathan Lemon #define IDA_CONTROLLER 0 /* drive "number" for controller */ 96db57feb7SJonathan Lemon 976b5b57aeSJohn Baldwin struct ida_softc; 986b5b57aeSJohn Baldwin 99db57feb7SJonathan Lemon struct ida_qcb { 100db57feb7SJonathan Lemon struct ida_hardware_qcb *hwqcb; 1016b5b57aeSJohn Baldwin struct ida_softc *ida; 102db57feb7SJonathan Lemon qcb_state state; 103db57feb7SJonathan Lemon short flags; 104db57feb7SJonathan Lemon union { 105e3975643SJake Burkholder STAILQ_ENTRY(ida_qcb) stqe; 106e3975643SJake Burkholder SLIST_ENTRY(ida_qcb) sle; 107db57feb7SJonathan Lemon } link; 108db57feb7SJonathan Lemon bus_dmamap_t dmamap; 109ee7eb00eSJonathan Lemon bus_addr_t hwqcb_busaddr; 1108177437dSPoul-Henning Kamp struct bio *buf; /* bio associated with qcb */ 1116b5b57aeSJohn Baldwin int error; 112db57feb7SJonathan Lemon }; 113db57feb7SJonathan Lemon 114ee7eb00eSJonathan Lemon struct ida_access { 115ee7eb00eSJonathan Lemon int (*fifo_full)(struct ida_softc *); 116ee7eb00eSJonathan Lemon void (*submit)(struct ida_softc *, struct ida_qcb *); 117ee7eb00eSJonathan Lemon bus_addr_t (*done)(struct ida_softc *); 118ee7eb00eSJonathan Lemon int (*int_pending)(struct ida_softc *); 119ee7eb00eSJonathan Lemon void (*int_enable)(struct ida_softc *, int); 120ee7eb00eSJonathan Lemon }; 121ee7eb00eSJonathan Lemon 122db57feb7SJonathan Lemon /* 123db57feb7SJonathan Lemon * flags for the controller 124db57feb7SJonathan Lemon */ 12555d782fcSJonathan Lemon #define IDA_ATTACHED 0x01 /* attached */ 1261277c3baSJonathan Lemon #define IDA_FIRMWARE 0x02 /* firmware must be started */ 12755d782fcSJonathan Lemon #define IDA_INTERRUPTS 0x04 /* interrupts enabled */ 1286b5b57aeSJohn Baldwin #define IDA_QFROZEN 0x08 /* request queue frozen */ 129db57feb7SJonathan Lemon 130db57feb7SJonathan Lemon struct ida_softc { 131db57feb7SJonathan Lemon device_t dev; 13284339b16SMatthew N. Dodd 13384339b16SMatthew N. Dodd struct callout ch; 13489c9c53dSPoul-Henning Kamp struct cdev *ida_dev_t; 135db57feb7SJonathan Lemon 136db57feb7SJonathan Lemon int regs_res_type; 137db57feb7SJonathan Lemon int regs_res_id; 138db57feb7SJonathan Lemon struct resource *regs; 139db57feb7SJonathan Lemon 140db57feb7SJonathan Lemon int irq_res_type; 141db57feb7SJonathan Lemon struct resource *irq; 142db57feb7SJonathan Lemon void *ih; 143db57feb7SJonathan Lemon 1446b5b57aeSJohn Baldwin struct mtx lock; 1456b5b57aeSJohn Baldwin struct intr_config_hook ich; 146db57feb7SJonathan Lemon 147db57feb7SJonathan Lemon /* various DMA tags */ 148db57feb7SJonathan Lemon bus_dma_tag_t parent_dmat; 149db57feb7SJonathan Lemon bus_dma_tag_t buffer_dmat; 150db57feb7SJonathan Lemon 151db57feb7SJonathan Lemon bus_dma_tag_t hwqcb_dmat; 152db57feb7SJonathan Lemon bus_dmamap_t hwqcb_dmamap; 153db57feb7SJonathan Lemon bus_addr_t hwqcb_busaddr; 154db57feb7SJonathan Lemon 155db57feb7SJonathan Lemon bus_dma_tag_t sg_dmat; 156db57feb7SJonathan Lemon 157db57feb7SJonathan Lemon int flags; 158db57feb7SJonathan Lemon 15984339b16SMatthew N. Dodd int qactive; 16084339b16SMatthew N. Dodd 161db57feb7SJonathan Lemon struct ida_hardware_qcb *hwqcbs; /* HW QCB array */ 162db57feb7SJonathan Lemon struct ida_qcb *qcbs; /* kernel QCB array */ 163e3975643SJake Burkholder SLIST_HEAD(, ida_qcb) free_qcbs; 164e3975643SJake Burkholder STAILQ_HEAD(, ida_qcb) qcb_queue; 1658177437dSPoul-Henning Kamp struct bio_queue_head bio_queue; 166ee7eb00eSJonathan Lemon 167ee7eb00eSJonathan Lemon struct ida_access cmd; 168db57feb7SJonathan Lemon }; 169db57feb7SJonathan Lemon 170db57feb7SJonathan Lemon /* 171db57feb7SJonathan Lemon * drive flags 172db57feb7SJonathan Lemon */ 173db57feb7SJonathan Lemon #define DRV_WRITEPROT 0x0001 174db57feb7SJonathan Lemon 17581530866SMatthew N. Dodd struct idad_softc { 176db57feb7SJonathan Lemon device_t dev; 177db57feb7SJonathan Lemon struct ida_softc *controller; 1780b7ed341SPoul-Henning Kamp struct disk *disk; 1791277c3baSJonathan Lemon int drive; /* per controller */ 1801277c3baSJonathan Lemon int unit; /* global */ 181db57feb7SJonathan Lemon int cylinders; 182db57feb7SJonathan Lemon int heads; 183db57feb7SJonathan Lemon int sectors; 184db57feb7SJonathan Lemon int secsize; 185db57feb7SJonathan Lemon int secperunit; 186db57feb7SJonathan Lemon int flags; 187db57feb7SJonathan Lemon }; 188db57feb7SJonathan Lemon 189ee7eb00eSJonathan Lemon struct ida_board { 190ee7eb00eSJonathan Lemon u_int32_t board; 191ee7eb00eSJonathan Lemon char *desc; 192ee7eb00eSJonathan Lemon struct ida_access *accessor; 1937c258c0eSJonathan Lemon int flags; 194ee7eb00eSJonathan Lemon }; 195ee7eb00eSJonathan Lemon 196ee7eb00eSJonathan Lemon extern int ida_detach(device_t dev); 197db57feb7SJonathan Lemon extern struct ida_softc *ida_alloc(device_t dev, struct resource *regs, 198db57feb7SJonathan Lemon int regs_type, int regs_id, bus_dma_tag_t parent_dmat); 199db57feb7SJonathan Lemon extern void ida_free(struct ida_softc *ida); 200a7f3dd6fSHans Petter Selasky extern int ida_setup(struct ida_softc *ida); 201db57feb7SJonathan Lemon extern int ida_command(struct ida_softc *ida, int command, void *data, 20255d782fcSJonathan Lemon int datasize, int drive, u_int32_t pblkno, int flags); 2038177437dSPoul-Henning Kamp extern void ida_submit_buf(struct ida_softc *ida, struct bio *bp); 204db57feb7SJonathan Lemon extern void ida_intr(void *data); 205db57feb7SJonathan Lemon 20681530866SMatthew N. Dodd extern void idad_intr(struct bio *bp); 207db57feb7SJonathan Lemon 208db57feb7SJonathan Lemon #endif /* _IDAVAR_H */ 209