Device layer rollup commit.
[dragonfly.git] / sys / dev / raid / ips / ips.h
CommitLineData
edc6143b
DR
1/*-
2 * Copyright (c) 2002 Adaptec Inc.
3 * All rights reserved.
4 *
5 * Written by: David Jeffery
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: src/sys/dev/ips/ips.h,v 1.5 2003/11/27 08:37:36 mbr Exp $
e4c9c0c8 29 * $DragonFly: src/sys/dev/raid/ips/ips.h,v 1.2 2004/05/19 22:52:47 dillon Exp $
edc6143b
DR
30 */
31
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/bus.h>
37#include <sys/conf.h>
38#include <sys/types.h>
39#include <sys/queue.h>
40#include <sys/buf.h>
41#include <sys/malloc.h>
42#include <sys/time.h>
43
44#include <machine/bus_memio.h>
45#include <machine/bus.h>
46#include <sys/rman.h>
47#include <machine/resource.h>
48
49#include <bus/pci/pcireg.h>
50#include <bus/pci/pcivar.h>
51
52/*
53 * IPS CONSTANTS
54 */
55#define IPS_VENDOR_ID 0x1014
56#define IPS_MORPHEUS_DEVICE_ID 0x01BD
57#define IPS_COPPERHEAD_DEVICE_ID 0x002E
58#define IPS_CSL 0xff
59#define IPS_POCL 0x30
60
61/* amounts of memory to allocate for certain commands */
62#define IPS_ADAPTER_INFO_LEN (sizeof(ips_adapter_info_t))
63#define IPS_DRIVE_INFO_LEN (sizeof(ips_drive_info_t))
64#define IPS_COMMAND_LEN 24
65#define IPS_MAX_SG_LEN (sizeof(ips_sg_element_t) * IPS_MAX_SG_ELEMENTS)
66#define IPS_NVRAM_PAGE_SIZE 128
67/* various flags */
68#define IPS_NOWAIT_FLAG 1
69
70/* states for the card to be in */
71#define IPS_DEV_OPEN 0x01
72#define IPS_TIMEOUT 0x02 /* command time out, need reset */
73#define IPS_OFFLINE 0x04 /* can't reset card/card failure */
74
75/* max number of commands set to something low for now */
76#define IPS_MAX_CMD_NUM 128
77#define IPS_MAX_NUM_DRIVES 8
78#define IPS_MAX_SG_ELEMENTS 32
79#define IPS_MAX_IOBUF_SIZE (64 * 1024)
80#define IPS_BLKSIZE 512
81
82/* logical drive states */
83
84#define IPS_LD_OFFLINE 0x02
85#define IPS_LD_OKAY 0x03
86#define IPS_LD_DEGRADED 0x04
87#define IPS_LD_FREE 0x00
88#define IPS_LD_SYS 0x06
89#define IPS_LD_CRS 0x24
90
91/* register offsets */
92#define MORPHEUS_REG_OMR0 0x0018 /* Outbound Msg. Reg. 0 */
93#define MORPHEUS_REG_OMR1 0x001C /* Outbound Msg. Reg. 1 */
94#define MORPHEUS_REG_IDR 0x0020 /* Inbound Doorbell Reg. */
95#define MORPHEUS_REG_IISR 0x0024 /* Inbound IRQ Status Reg. */
96#define MORPHEUS_REG_IIMR 0x0028 /* Inbound IRQ Mask Reg. */
97#define MORPHEUS_REG_OISR 0x0030 /* Outbound IRQ Status Reg. */
98#define MORPHEUS_REG_OIMR 0x0034 /* Outbound IRQ Status Reg. */
99#define MORPHEUS_REG_IQPR 0x0040 /* Inbound Queue Port Reg. */
100#define MORPHEUS_REG_OQPR 0x0044 /* Outbound Queue Port Reg. */
101
102#define COPPER_REG_SCPR 0x05 /* Subsystem Ctrl. Port Reg. */
103#define COPPER_REG_ISPR 0x06 /* IRQ Status Port Reg. */
104#define COPPER_REG_CBSP 0x07 /* ? Reg. */
105#define COPPER_REG_HISR 0x08 /* Host IRQ Status Reg. */
106#define COPPER_REG_CCSAR 0x10 /* Cmd. Channel Sys Addr Reg.*/
107#define COPPER_REG_CCCR 0x14 /* Cmd. Channel Ctrl. Reg. */
108#define COPPER_REG_SQHR 0x20 /* Status Queue Head Reg. */
109#define COPPER_REG_SQTR 0x24 /* Status Queue Tail Reg. */
110#define COPPER_REG_SQER 0x28 /* Status Queue End Reg. */
111#define COPPER_REG_SQSR 0x2C /* Status Queue Start Reg. */
112
113/* bit definitions */
114#define MORPHEUS_BIT_POST1 0x01
115#define MORPHEUS_BIT_POST2 0x02
116#define MORPHEUS_BIT_CMD_IRQ 0x08
117
118#define COPPER_CMD_START 0x101A
119#define COPPER_SEM_BIT 0x08
120#define COPPER_EI_BIT 0x80
121#define COPPER_EBM_BIT 0x02
122#define COPPER_RESET_BIT 0x80
123#define COPPER_GHI_BIT 0x04
124#define COPPER_SCE_BIT 0x01
125#define COPPER_OP_BIT 0x01
126#define COPPER_ILE_BIT 0x10
127
128/* status defines */
129#define IPS_POST1_OK 0x8000
130#define IPS_POST2_OK 0x000f
131
132/* command op codes */
133#define IPS_READ_CMD 0x02
134#define IPS_WRITE_CMD 0x03
135#define IPS_ADAPTER_INFO_CMD 0x05
136#define IPS_CACHE_FLUSH_CMD 0x0A
137#define IPS_REBUILD_STATUS_CMD 0x0C
138#define IPS_ERROR_TABLE_CMD 0x17
139#define IPS_DRIVE_INFO_CMD 0x19
140#define IPS_SUBSYS_PARAM_CMD 0x40
141#define IPS_CONFIG_SYNC_CMD 0x58
142#define IPS_SG_READ_CMD 0x82
143#define IPS_SG_WRITE_CMD 0x83
144#define IPS_RW_NVRAM_CMD 0xBC
145#define IPS_FFDC_CMD 0xD7
146
147/* error information returned by the adapter */
148#define IPS_MIN_ERROR 0x02
149#define IPS_ERROR_STATUS 0x13000200 /* ahh, magic numbers */
150
151#define IPS_OS_FREEBSD 8
152#define IPS_VERSION_MAJOR "0.90"
153#define IPS_VERSION_MINOR ".10"
154
155/* Adapter Types */
156#define IPS_ADAPTER_COPPERHEAD 0x01
157#define IPS_ADAPTER_COPPERHEAD2 0x02
158#define IPS_ADAPTER_COPPERHEADOB1 0x03
159#define IPS_ADAPTER_COPPERHEADOB2 0x04
160#define IPS_ADAPTER_CLARINET 0x05
161#define IPS_ADAPTER_CLARINETLITE 0x06
162#define IPS_ADAPTER_TROMBONE 0x07
163#define IPS_ADAPTER_MORPHEUS 0x08
164#define IPS_ADAPTER_MORPHEUSLITE 0x09
165#define IPS_ADAPTER_NEO 0x0A
166#define IPS_ADAPTER_NEOLITE 0x0B
167#define IPS_ADAPTER_SARASOTA2 0x0C
168#define IPS_ADAPTER_SARASOTA1 0x0D
169#define IPS_ADAPTER_MARCO 0x0E
170#define IPS_ADAPTER_SEBRING 0x0F
171#define IPS_ADAPTER_MAX_T IPS_ADAPTER_SEBRING
172
173/* values for ffdc_settime (from gmtime) */
174#define IPS_SECSPERMIN 60
175#define IPS_MINSPERHOUR 60
176#define IPS_HOURSPERDAY 24
177#define IPS_DAYSPERWEEK 7
178#define IPS_DAYSPERNYEAR 365
179#define IPS_DAYSPERLYEAR 366
180#define IPS_SECSPERHOUR (IPS_SECSPERMIN * IPS_MINSPERHOUR)
181#define IPS_SECSPERDAY ((long) IPS_SECSPERHOUR * IPS_HOURSPERDAY)
182#define IPS_MONSPERYEAR 12
183#define IPS_EPOCH_YEAR 1970
184#define IPS_LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
185#define ips_isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
186
187
188/*
189 * for compatibility
190 */
191/* struct buf to struct bio changes */
192#define BIO_ERROR B_ERROR
193#define BIO_READ B_READ
194#define bio buf
195#define bio_error b_error
196#define bio_flags b_flags
197#define bio_driver1 b_driver1
198#define bio_pblkno b_pblkno
199#define bio_data b_data
200#define bio_bcount b_bcount
201#define bio_dev b_dev
202#define bio_resid b_resid
203
204/* geom */
205#define bio_disk bio_dev
206#define d_drv1 si_drv1
207#define d_maxsize si_iosize_max
208
209struct mtx {
210 volatile int locked;
211 intrmask_t spl;
212};
213
214#define IPS_LOCK_INIT(sc) (sc)->cmd_mtx.locked = 0
215#define IPS_LOCK(sc) do { \
216 int s = splbio(); \
217 if ((sc)->cmd_mtx.locked++ == 0) \
218 (sc)->cmd_mtx.spl = s; \
219 else \
220 splx(s); \
221} while (0)
222#define IPS_UNLOCK(sc) do { \
223 if ((sc)->cmd_mtx.locked) { \
224 if (--((sc)->cmd_mtx.locked) == 0) \
225 splx((sc)->cmd_mtx.spl); \
226 } \
227} while (0)
228#define IPS_LOCK_FREE(sc)
229
230#define disk_open_t d_open_t
231#define disk_close_t d_close_t
232#define disk_strategy_t d_strategy_t
233
234#if defined(PCIR_MAPS) && !defined(PCIR_BARS)
235# define PCIR_BAR(x) (PCIR_BARS + (x) * 4)
236# define PCIR_BARS PCIR_MAPS
237#endif
238
239
240/*
241 * IPS MACROS
242 */
243
244#define ips_read_1(sc,offset) bus_space_read_1(sc->bustag, sc->bushandle, offset)
245#define ips_read_2(sc,offset) bus_space_read_2(sc->bustag, sc->bushandle, offset)
246#define ips_read_4(sc,offset) bus_space_read_4(sc->bustag, sc->bushandle, offset)
247
248#define ips_write_1(sc,offset,value) bus_space_write_1(sc->bustag, sc->bushandle, offset, value)
249#define ips_write_2(sc,offset,value) bus_space_write_2(sc->bustag, sc->bushandle, offset, value)
250#define ips_write_4(sc,offset,value) bus_space_write_4(sc->bustag, sc->bushandle, offset, value)
251
252#define ips_read_request(iobuf) ((iobuf)->b_flags & B_READ)
253
254/* this is ugly. It zeros the end elements in an ips_command_t struct starting with the status element */
255#define clear_ips_command(command) bzero(&((command)->status), (unsigned long)(&(command)[1])-(unsigned long)&((command)->status))
256
257#define COMMAND_ERROR(status) (((status)->fields.basic_status & 0x0f) >= IPS_MIN_ERROR)
258
259#ifndef IPS_DEBUG
260#define DEVICE_PRINTF(x...)
261#define PRINTF(x...)
262#else
263#define DEVICE_PRINTF(level,x...) if(IPS_DEBUG >= level)device_printf(x)
264#define PRINTF(level,x...) if(IPS_DEBUG >= level)printf(x)
265#endif
266
267/*
268 * IPS STRUCTS
269 */
270struct ips_softc;
271
272typedef struct {
273 u_int8_t command;
274 u_int8_t id;
275 u_int8_t drivenum;
276 u_int8_t reserve2;
277 u_int32_t lba;
278 u_int32_t buffaddr;
279 u_int32_t reserve3;
280} __attribute__ ((packed)) ips_generic_cmd;
281
282typedef struct {
283 u_int8_t command;
284 u_int8_t id;
285 u_int8_t drivenum;
286 u_int8_t segnum;
287 u_int32_t lba;
288 u_int32_t buffaddr;
289 u_int16_t length;
290 u_int16_t reserve1;
291} __attribute__ ((packed)) ips_io_cmd;
292
293typedef struct {
294 u_int8_t command;
295 u_int8_t id;
296 u_int8_t pagenum;
297 u_int8_t rw;
298 u_int32_t reserve1;
299 u_int32_t buffaddr;
300 u_int32_t reserve3;
301} __attribute__ ((packed)) ips_rw_nvram_cmd;
302
303typedef struct {
304 u_int8_t command;
305 u_int8_t id;
306 u_int8_t drivenum;
307 u_int8_t reserve1;
308 u_int32_t reserve2;
309 u_int32_t buffaddr;
310 u_int32_t reserve3;
311} __attribute__ ((packed)) ips_drive_cmd;
312
313typedef struct {
314 u_int8_t command;
315 u_int8_t id;
316 u_int8_t reserve1;
317 u_int8_t commandtype;
318 u_int32_t reserve2;
319 u_int32_t buffaddr;
320 u_int32_t reserve3;
321} __attribute__((packed)) ips_adapter_info_cmd;
322
323typedef struct {
324 u_int8_t command;
325 u_int8_t id;
326 u_int8_t reset_count;
327 u_int8_t reset_type;
328 u_int8_t second;
329 u_int8_t minute;
330 u_int8_t hour;
331 u_int8_t day;
332 u_int8_t reserve1[4];
333 u_int8_t month;
334 u_int8_t yearH;
335 u_int8_t yearL;
336 u_int8_t reserve2;
337} __attribute__((packed)) ips_adapter_ffdc_cmd;
338
339typedef union{
340 ips_generic_cmd generic_cmd;
341 ips_drive_cmd drive_cmd;
342 ips_adapter_info_cmd adapter_info_cmd;
343} ips_cmd_buff_t;
344
345typedef struct {
346 u_int32_t signature;
347 u_int8_t reserved;
348 u_int8_t adapter_slot;
349 u_int16_t adapter_type;
350 u_int8_t bios_high[4];
351 u_int8_t bios_low[4];
352 u_int16_t reserve2;
353 u_int8_t reserve3;
354 u_int8_t operating_system;
355 u_int8_t driver_high[4];
356 u_int8_t driver_low[4];
357 u_int8_t reserve4[100];
358} __attribute__((packed)) ips_nvram_page5;
359
360typedef struct {
361 u_int32_t addr;
362 u_int32_t len;
363} ips_sg_element_t;
364
365typedef struct {
366 u_int8_t drivenum;
367 u_int8_t merge_id;
368 u_int8_t raid_lvl;
369 u_int8_t state;
370 u_int32_t sector_count;
371} __attribute__((packed)) ips_drive_t;
372
373typedef struct {
374 u_int8_t drivecount;
375 u_int8_t reserve1;
376 u_int16_t reserve2;
377 ips_drive_t drives[IPS_MAX_NUM_DRIVES];
378} __attribute__((packed)) ips_drive_info_t;
379
380typedef struct {
381 u_int8_t drivecount;
382 u_int8_t miscflags;
383 u_int8_t SLTflags;
384 u_int8_t BSTflags;
385 u_int8_t pwr_chg_count;
386 u_int8_t wrong_addr_count;
387 u_int8_t unident_count;
388 u_int8_t nvram_dev_chg_count;
389 u_int8_t codeblock_version[8];
390 u_int8_t bootblock_version[8];
391 u_int32_t drive_sector_count[IPS_MAX_NUM_DRIVES];
392 u_int8_t max_concurrent_cmds;
393 u_int8_t max_phys_devices;
394 u_int16_t flash_prog_count;
395 u_int8_t defunct_disks;
396 u_int8_t rebuildflags;
397 u_int8_t offline_drivecount;
398 u_int8_t critical_drivecount;
399 u_int16_t config_update_count;
400 u_int8_t blockedflags;
401 u_int8_t psdn_error;
402 u_int16_t addr_dead_disk[4*16]; /* ugly, max # channels * max # scsi devices per channel */
403} __attribute__((packed)) ips_adapter_info_t;
404
405typedef struct {
406 u_int32_t status[IPS_MAX_CMD_NUM];
407 u_int32_t base_phys_addr;
408 int nextstatus;
409 bus_dma_tag_t dmatag;
410 bus_dmamap_t dmamap;
411} ips_copper_queue_t;
412
413typedef union {
414 struct {
415 u_int8_t reserved;
416 u_int8_t command_id;
417 u_int8_t basic_status;
418 u_int8_t extended_status;
419 } fields;
420 volatile u_int32_t value;
421} ips_cmd_status_t;
422
423/* used to keep track of current commands to the card */
424typedef struct ips_command {
425 u_int8_t command_number;
426 u_int8_t id;
427 u_int8_t timeout;
428 struct ips_softc *sc;
429 bus_dmamap_t command_dmamap;
430 void *command_buffer;
431 u_int32_t command_phys_addr; /*WARNING! must be changed if 64bit addressing ever used*/
432 ips_cmd_status_t status;
433 SLIST_ENTRY(ips_command) next;
434 bus_dma_tag_t data_dmatag;
435 bus_dmamap_t data_dmamap;
436 void *data_buffer;
437 void *arg;
438 void (*callback)(struct ips_command *command);
439} ips_command_t;
440
441typedef struct ips_wait_list {
442 STAILQ_ENTRY(ips_wait_list) next;
443 void *data;
444 int (* callback)(ips_command_t *command);
445} ips_wait_list_t;
446
447typedef struct ips_softc {
448 struct resource *iores;
449 struct resource *irqres;
450 struct intr_config_hook ips_ich;
451 int configured;
452 int state;
453 int iotype;
454 int rid;
455 int irqrid;
456 void *irqcookie;
457 bus_space_tag_t bustag;
458 bus_space_handle_t bushandle;
459 bus_dma_tag_t adapter_dmatag;
460 bus_dma_tag_t command_dmatag;
461 bus_dma_tag_t sg_dmatag;
462 device_t dev;
edc6143b
DR
463 struct callout_handle timer;
464 u_int16_t adapter_type;
465 ips_adapter_info_t adapter_info;
466 device_t diskdev[IPS_MAX_NUM_DRIVES];
467 ips_drive_t drives[IPS_MAX_NUM_DRIVES];
468 u_int8_t drivecount;
469 u_int16_t ffdc_resetcount;
470 struct timeval ffdc_resettime;
471 u_int8_t next_drive;
472 u_int8_t max_cmds;
473 volatile u_int8_t used_commands;
474 ips_command_t commandarray[IPS_MAX_CMD_NUM];
475 SLIST_HEAD(command_list, ips_command) free_cmd_list;
476 STAILQ_HEAD(command_wait_list,ips_wait_list) cmd_wait_list;
477 int (*ips_adapter_reinit)(struct ips_softc *sc,
478 int force);
479 void (*ips_adapter_intr)(void *sc);
480 void (*ips_issue_cmd)(ips_command_t *command);
481 ips_copper_queue_t *copper_queue;
482 struct mtx cmd_mtx;
483} ips_softc_t;
484
485/* function defines from ips_ioctl.c */
486extern int ips_ioctl_request(ips_softc_t *sc, u_long ioctl_cmd, caddr_t addr,
487 int32_t flags);
488/* function defines from ips_disk.c */
489extern void ipsd_finish(struct bio *iobuf);
490
491/* function defines from ips_commands.c */
492extern int ips_flush_cache(ips_softc_t *sc);
493extern void ips_start_io_request(ips_softc_t *sc, struct bio *iobuf);
494extern int ips_get_drive_info(ips_softc_t *sc);
495extern int ips_get_adapter_info(ips_softc_t *sc);
496extern int ips_ffdc_reset(ips_softc_t *sc);
497extern int ips_update_nvram(ips_softc_t *sc);
498extern int ips_clear_adapter(ips_softc_t *sc);
499
500/* function defines from ips.c */
501extern int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *),
502 void *data, unsigned long flags);
503extern void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command);
504extern int ips_adapter_init(ips_softc_t *sc);
505extern int ips_morpheus_reinit(ips_softc_t *sc, int force);
506extern int ips_adapter_free(ips_softc_t *sc);
507extern void ips_morpheus_intr(void *sc);
508extern void ips_issue_morpheus_cmd(ips_command_t *command);
509extern int ips_copperhead_reinit(ips_softc_t *sc, int force);
510extern void ips_copperhead_intr(void *sc);
511extern void ips_issue_copperhead_cmd(ips_command_t *command);
512
513#define IPS_CDEV_MAJOR 175
514#define IPSD_CDEV_MAJOR 176