Annotation of sys/dev/ic/gdtvar.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: gdtvar.h,v 1.13 2007/04/28 00:34:25 deraadt Exp $ */
! 2:
! 3: /*
! 4: * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: * 1. Redistributions of source code must retain the above copyright
! 10: * notice, this list of conditions and the following disclaimer.
! 11: * 2. Redistributions in binary form must reproduce the above copyright
! 12: * notice, this list of conditions and the following disclaimer in the
! 13: * documentation and/or other materials provided with the distribution.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 16: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 17: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 18: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 19: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 20: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 21: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 22: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 23: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 24: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: /*
! 28: * This driver would not have written if it was not for the hardware donations
! 29: * from both ICP-Vortex and Öko.neT. I want to thank them for their support.
! 30: */
! 31:
! 32: #define DEVNAME(s) ((s)->sc_dev.dv_xname)
! 33: #define GDT_CMD_RESERVE 4 /* Internal driver cmd reserve. */
! 34:
! 35: #define GDT_IOCTL_DUMMY _IOWR('B', 32, struct gdt_dummy)
! 36: struct gdt_dummy {
! 37: void *cookie;
! 38: int x;
! 39: };
! 40:
! 41: /* XXX Is this pragma necessary? */
! 42: #pragma pack(1)
! 43:
! 44: #define GDT_SCRATCH_SZ 4096
! 45:
! 46: #define GDT_IOCTL_GENERAL _IOWR('B', 33, gdt_ucmd_t) /* general IOCTL */
! 47: typedef struct gdt_ucmd {
! 48: void *cookie;
! 49: u_int16_t io_node;
! 50: u_int16_t service;
! 51: u_int32_t timeout;
! 52: u_int16_t status;
! 53: u_int32_t info;
! 54:
! 55: u_int32_t BoardNode; /* board node (always 0) */
! 56: u_int32_t CommandIndex; /* command number */
! 57: u_int16_t OpCode; /* the command (READ,..) */
! 58: union {
! 59: struct {
! 60: u_int16_t DeviceNo; /* number of cache drive */
! 61: u_int32_t BlockNo; /* block number */
! 62: u_int32_t BlockCnt; /* block count */
! 63: void *DestAddr; /* data */
! 64: } cache; /* cache service cmd. str. */
! 65: struct {
! 66: u_int16_t param_size; /* size of p_param buffer */
! 67: u_int32_t subfunc; /* IOCTL function */
! 68: u_int32_t channel; /* device */
! 69: void *p_param; /* data */
! 70: } ioctl; /* IOCTL command structure */
! 71: struct {
! 72: u_int16_t reserved;
! 73: u_int32_t direction; /* data direction */
! 74: u_int32_t mdisc_time; /* disc. time (0: no timeout)*/
! 75: u_int32_t mcon_time; /* connect time(0: no to.) */
! 76: void *sdata; /* dest. addr. (if s/g: -1) */
! 77: u_int32_t sdlen; /* data length (bytes) */
! 78: u_int32_t clen; /* SCSI cmd. length(6,10,12) */
! 79: u_int8_t cmd[12]; /* SCSI command */
! 80: u_int8_t target; /* target ID */
! 81: u_int8_t lun; /* LUN */
! 82: u_int8_t bus; /* SCSI bus number */
! 83: u_int8_t priority; /* only 0 used */
! 84: u_int32_t sense_len; /* sense data length */
! 85: void *sense_data; /* sense data addr. */
! 86: u_int32_t link_p; /* linked cmds (not supp.) */
! 87: } raw; /* raw service cmd. struct. */
! 88: } u;
! 89: u_int8_t data[GDT_SCRATCH_SZ];
! 90: int complete_flag;
! 91: TAILQ_ENTRY(gdt_ucmd) links;
! 92: } gdt_ucmd_t;
! 93:
! 94: #define GDT_IOCTL_DRVERS _IOWR('B', 34, int) /* get driver version */
! 95: typedef struct gdt_drvers {
! 96: void *cookie;
! 97: int vers;
! 98: } gdt_drvers_t;
! 99:
! 100: #define GDT_IOCTL_CTRTYPE _IOR('B', 35, gdt_ctrt_t) /* get ctr. type */
! 101: typedef struct gdt_ctrt {
! 102: void *cookie;
! 103: u_int16_t io_node;
! 104: u_int16_t oem_id;
! 105: u_int16_t type;
! 106: u_int32_t info;
! 107: u_int8_t access;
! 108: u_int8_t remote;
! 109: u_int16_t ext_type;
! 110: u_int16_t device_id;
! 111: u_int16_t sub_device_id;
! 112: } gdt_ctrt_t;
! 113:
! 114: #define GDT_IOCTL_OSVERS _IOR('B', 36, gdt_osv_t) /* get OS version */
! 115: typedef struct gdt_osv {
! 116: void *cookie;
! 117: u_int8_t oscode;
! 118: u_int8_t version;
! 119: u_int8_t subversion;
! 120: u_int16_t revision;
! 121: char name[64];
! 122: } gdt_osv_t;
! 123:
! 124: #define GDT_IOCTL_CTRCNT _IOR('B', 37, int) /* get ctr. count */
! 125: typedef struct gdt_ctrcnt {
! 126: void *cookie;
! 127: int cnt;
! 128: } gdt_ctrcnt_t;
! 129:
! 130: #define GDT_IOCTL_EVENT _IOWR('B', 38, gdt_event_t) /* get event */
! 131:
! 132: typedef struct {
! 133: u_int16_t size; /* size of structure */
! 134: union {
! 135: char stream[16];
! 136: struct {
! 137: u_int16_t ionode;
! 138: u_int16_t service;
! 139: u_int32_t index;
! 140: } driver;
! 141: struct {
! 142: u_int16_t ionode;
! 143: u_int16_t service;
! 144: u_int16_t status;
! 145: u_int32_t info;
! 146: u_int8_t scsi_coord[3];
! 147: } async;
! 148: struct {
! 149: u_int16_t ionode;
! 150: u_int16_t service;
! 151: u_int16_t status;
! 152: u_int32_t info;
! 153: u_int16_t hostdrive;
! 154: u_int8_t scsi_coord[3];
! 155: u_int8_t sense_key;
! 156: } sync;
! 157: struct {
! 158: u_int32_t l1, l2, l3, l4;
! 159: } test;
! 160: } eu;
! 161: u_int32_t severity;
! 162: u_int8_t event_string[256];
! 163: } gdt_evt_data;
! 164: #define GDT_ES_ASYNC 1
! 165: #define GDT_ES_DRIVER 2
! 166: #define GDT_ES_TEST 3
! 167: #define GDT_ES_SYNC 4
! 168:
! 169: /* dvrevt structure */
! 170: typedef struct {
! 171: u_int32_t first_stamp;
! 172: u_int32_t last_stamp;
! 173: u_int16_t same_count;
! 174: u_int16_t event_source;
! 175: u_int16_t event_idx;
! 176: u_int8_t application;
! 177: u_int8_t reserved;
! 178: gdt_evt_data event_data;
! 179: } gdt_evt_str;
! 180:
! 181: typedef struct gdt_event {
! 182: void *cookie;
! 183: int erase;
! 184: int handle;
! 185: gdt_evt_str dvr;
! 186: } gdt_event_t;
! 187:
! 188: #define GDT_IOCTL_STATIST _IOR('B', 39, gdt_statist_t) /* get statistics */
! 189: typedef struct gdt_statist {
! 190: void *cookie;
! 191: u_int16_t io_count_act;
! 192: u_int16_t io_count_max;
! 193: u_int16_t req_queue_act;
! 194: u_int16_t req_queue_max;
! 195: u_int16_t cmd_index_act;
! 196: u_int16_t cmd_index_max;
! 197: u_int16_t sg_count_act;
! 198: u_int16_t sg_count_max;
! 199: } gdt_statist_t;
! 200:
! 201: #pragma pack()
! 202:
! 203: #ifdef _KERNEL
! 204:
! 205: /* Debugging */
! 206: /* #define GDT_DEBUG GDT_D_IOCTL | GDT_D_INFO */
! 207: #ifdef GDT_DEBUG
! 208: #define GDT_DPRINTF(mask, args) if (gdt_debug & (mask)) printf args
! 209: #define GDT_D_INTR 0x01
! 210: #define GDT_D_MISC 0x02
! 211: #define GDT_D_CMD 0x04
! 212: #define GDT_D_QUEUE 0x08
! 213: #define GDT_D_IO 0x10
! 214: #define GDT_D_IOCTL 0x20
! 215: #define GDT_D_INFO 0x40
! 216: extern int gdt_debug;
! 217: #else
! 218: #define GDT_DPRINTF(mask, args)
! 219: #endif
! 220:
! 221: /* Miscellaneous constants */
! 222: #define GDT_RETRIES 100000000 /* 100000 * 1us = 100s */
! 223: #define GDT_TIMEOUT 100000000 /* 100000 * 1us = 100s */
! 224: #define GDT_POLL_TIMEOUT 10000000 /* 10000 * 1us = 10s */
! 225: #define GDT_WATCH_TIMEOUT 10000 /* 10000 * 1ms = 10s */
! 226:
! 227: /* Context structure for interrupt services */
! 228: struct gdt_intr_ctx {
! 229: u_int32_t info, info2;
! 230: u_int16_t cmd_status, service;
! 231: u_int8_t istatus;
! 232: };
! 233:
! 234: /*
! 235: * A command contol block, one for each corresponding command index of the
! 236: * controller.
! 237: */
! 238: struct gdt_ccb {
! 239: TAILQ_ENTRY(gdt_ccb) gc_chain;
! 240: struct scsi_xfer *gc_xs;
! 241: struct gdt_ucmd *gc_ucmd;
! 242: bus_dmamap_t gc_dmamap_xfer;
! 243: int gc_timeout;
! 244: u_int32_t gc_info;
! 245: u_int32_t gc_blockno;
! 246: u_int32_t gc_blockcnt;
! 247: u_int16_t gc_status;
! 248: u_int8_t gc_service;
! 249: u_int8_t gc_cmd_index;
! 250: u_int8_t gc_flags;
! 251: #define GDT_GCF_CMD_MASK 0x3
! 252: #define GDT_GCF_UNUSED 0
! 253: #define GDT_GCF_INTERNAL 1
! 254: #define GDT_GCF_SCREEN 2
! 255: #define GDT_GCF_SCSI 3
! 256: #define GDT_GCF_WATCHDOG 0x4
! 257: };
! 258:
! 259: static __inline__ int gdt_ccb_set_cmd(struct gdt_ccb *, int);
! 260: static __inline__ int
! 261: gdt_ccb_set_cmd(ccb, flag)
! 262: struct gdt_ccb *ccb;
! 263: int flag;
! 264: {
! 265: int rv = ccb->gc_flags & GDT_GCF_CMD_MASK;
! 266:
! 267: ccb->gc_flags &= ~GDT_GCF_CMD_MASK;
! 268: ccb->gc_flags |= flag;
! 269: return (rv);
! 270: }
! 271:
! 272: struct gdt_softc {
! 273: struct device sc_dev;
! 274: void *sc_ih;
! 275: struct scsi_link sc_link; /* Virtual SCSI bus for cache devs */
! 276: struct scsi_link *sc_raw_link; /* Raw SCSI busses */
! 277:
! 278: int sc_class; /* Controller class */
! 279: #define GDT_ISA 0x01
! 280: #define GDT_EISA 0x02
! 281: #define GDT_PCI 0x03
! 282: #define GDT_PCINEW 0x04
! 283: #define GDT_MPR 0x05
! 284: #define GDT_CLASS_MASK 0x07
! 285: #define GDT_FC 0x10
! 286: #define GDT_CLASS(gdt) ((gdt)->sc_class & GDT_CLASS_MASK)
! 287:
! 288: bus_space_tag_t sc_dpmemt;
! 289: bus_space_handle_t sc_dpmemh;
! 290: bus_addr_t sc_dpmembase;
! 291: bus_dma_tag_t sc_dmat;
! 292:
! 293: /* XXX These could go into a class-dependent opaque struct instead */
! 294: bus_space_tag_t sc_iot;
! 295: bus_space_handle_t sc_ioh;
! 296: bus_addr_t sc_iobase;
! 297:
! 298: u_int16_t sc_ic_all_size;
! 299:
! 300: struct gdt_ccb sc_ccbs[GDT_MAXCMDS];
! 301: TAILQ_HEAD(, gdt_ccb) sc_free_ccb, sc_ccbq;
! 302: TAILQ_HEAD(, gdt_ucmd) sc_ucmdq;
! 303: LIST_HEAD(, scsi_xfer) sc_queue;
! 304: struct scsi_xfer *sc_queuelast;
! 305:
! 306: int sc_ndevs;
! 307:
! 308: u_int16_t sc_cmd_len;
! 309: u_int16_t sc_cmd_off;
! 310: u_int16_t sc_cmd_cnt;
! 311: u_int8_t sc_cmd[GDT_CMD_SZ];
! 312:
! 313: u_int32_t sc_info;
! 314: u_int32_t sc_info2;
! 315: bus_dma_segment_t sc_scratch_seg;
! 316: caddr_t sc_scratch;
! 317: u_int16_t sc_status;
! 318:
! 319: u_int8_t sc_bus_cnt;
! 320: u_int8_t sc_bus_id[GDT_MAXBUS];
! 321: u_int8_t sc_more_proc;
! 322:
! 323: u_int32_t sc_total_disks;
! 324:
! 325: struct {
! 326: u_int8_t hd_present;
! 327: u_int8_t hd_is_logdrv;
! 328: u_int8_t hd_is_arraydrv;
! 329: u_int8_t hd_is_master;
! 330: u_int8_t hd_is_parity;
! 331: u_int8_t hd_is_hotfix;
! 332: u_int8_t hd_master_no;
! 333: u_int8_t hd_lock;
! 334: u_int8_t hd_heads;
! 335: u_int8_t hd_secs;
! 336: u_int16_t hd_devtype;
! 337: u_int32_t hd_size;
! 338: u_int8_t hd_ldr_no;
! 339: u_int8_t hd_rw_attribs;
! 340: u_int32_t hd_start_sec;
! 341: } sc_hdr[GDT_MAX_HDRIVES];
! 342:
! 343: struct {
! 344: u_int8_t ra_lock; /* chan locked? (hot plug */
! 345: u_int8_t ra_phys_cnt; /* physical disk count */
! 346: u_int8_t ra_local_no; /* local channel number */
! 347: u_int8_t ra_io_cnt[GDT_MAXID]; /* current IO count */
! 348: u_int32_t ra_address; /* channel address */
! 349: u_int32_t ra_id_list[GDT_MAXID]; /* IDs of phys disks */
! 350: } sc_raw[GDT_MAXBUS]; /* SCSI channels */
! 351:
! 352: struct {
! 353: u_int32_t cp_version;
! 354: u_int16_t cp_state;
! 355: u_int16_t cp_strategy;
! 356: u_int16_t cp_write_back;
! 357: u_int16_t cp_block_size;
! 358: } sc_cpar;
! 359:
! 360: struct {
! 361: u_int32_t bi_ser_no; /* serial number */
! 362: u_int8_t bi_oem_id[2]; /* u_int8_t OEM ID */
! 363: u_int16_t bi_ep_flags; /* eprom flags */
! 364: u_int32_t bi_proc_id; /* processor ID */
! 365: u_int32_t bi_memsize; /* memory size (bytes) */
! 366: u_int8_t bi_mem_banks; /* memory banks */
! 367: u_int8_t bi_chan_type; /* channel type */
! 368: u_int8_t bi_chan_count; /* channel count */
! 369: u_int8_t bi_rdongle_pres; /* dongle present */
! 370: u_int32_t bi_epr_fw_ver; /* (eprom) firmware ver */
! 371: u_int32_t bi_upd_fw_ver; /* (update) firmware ver */
! 372: u_int32_t bi_upd_revision; /* update revision */
! 373: char bi_type_string[16]; /* char controller name */
! 374: char bi_raid_string[16]; /* char RAID firmware name */
! 375: u_int8_t bi_update_pres; /* update present? */
! 376: u_int8_t bi_xor_pres; /* XOR engine present */
! 377: u_int8_t bi_prom_type; /* ROM type (eprom/flash) */
! 378: u_int8_t bi_prom_count; /* number of ROM devices */
! 379: u_int32_t bi_dup_pres; /* duplexing module pres? */
! 380: u_int32_t bi_chan_pres; /* # of exp. channels */
! 381: u_int32_t bi_mem_pres; /* memory expansion inst? */
! 382: u_int8_t bi_ft_bus_system; /* fault bus supported? */
! 383: u_int8_t bi_subtype_valid; /* board_subtype valid */
! 384: u_int8_t bi_board_subtype; /* subtype/hardware level */
! 385: u_int8_t bi_rampar_pres; /* RAM parity check hw? */
! 386: } sc_binfo;
! 387:
! 388: struct {
! 389: u_int8_t bf_chaining; /* chaining supported */
! 390: u_int8_t bf_striping; /* striping (RAID-0) supported */
! 391: u_int8_t bf_mirroring; /* mirroring (RAID-1) supported */
! 392: u_int8_t bf_raid; /* RAID-4/5/10 supported */
! 393: } sc_bfeat;
! 394:
! 395: u_int16_t sc_raw_feat;
! 396: u_int16_t sc_cache_feat;
! 397:
! 398: void (*sc_copy_cmd)(struct gdt_softc *, struct gdt_ccb *);
! 399: u_int8_t (*sc_get_status)(struct gdt_softc *);
! 400: void (*sc_intr)(struct gdt_softc *, struct gdt_intr_ctx *);
! 401: void (*sc_release_event)(struct gdt_softc *, struct gdt_ccb *);
! 402: void (*sc_set_sema0)(struct gdt_softc *);
! 403: int (*sc_test_busy)(struct gdt_softc *);
! 404: };
! 405:
! 406: void gdtminphys(struct buf *);
! 407: int gdt_attach(struct gdt_softc *);
! 408: int gdt_intr(void *);
! 409:
! 410: #ifdef __GNUC__
! 411: /* These all require correctly aligned buffers */
! 412: static __inline__ void gdt_enc16(u_int8_t *, u_int16_t);
! 413: static __inline__ void gdt_enc32(u_int8_t *, u_int32_t);
! 414: static __inline__ u_int8_t gdt_dec8(u_int8_t *);
! 415: static __inline__ u_int16_t gdt_dec16(u_int8_t *);
! 416: static __inline__ u_int32_t gdt_dec32(u_int8_t *);
! 417:
! 418: static __inline__ void
! 419: gdt_enc16(addr, value)
! 420: u_int8_t *addr;
! 421: u_int16_t value;
! 422: {
! 423: *(u_int16_t *)addr = htole16(value);
! 424: }
! 425:
! 426: static __inline__ void
! 427: gdt_enc32(addr, value)
! 428: u_int8_t *addr;
! 429: u_int32_t value;
! 430: {
! 431: *(u_int32_t *)addr = htole32(value);
! 432: }
! 433:
! 434: static __inline__ u_int8_t
! 435: gdt_dec8(addr)
! 436: u_int8_t *addr;
! 437: {
! 438: return *(u_int8_t *)addr;
! 439: }
! 440:
! 441: static __inline__ u_int16_t
! 442: gdt_dec16(addr)
! 443: u_int8_t *addr;
! 444: {
! 445: return letoh16(*(u_int16_t *)addr);
! 446: }
! 447:
! 448: static __inline__ u_int32_t
! 449: gdt_dec32(addr)
! 450: u_int8_t *addr;
! 451: {
! 452: return letoh32(*(u_int32_t *)addr);
! 453: }
! 454: #endif
! 455:
! 456: extern u_int8_t gdt_polling;
! 457:
! 458: #endif
CVSweb