File:  [DragonFly] / src / sys / dev / raid / ips / ips.h
Revision 1.2: download - view: text, annotated - select for diffs
Wed May 19 22:52:47 2004 UTC (10 years, 5 months ago) by dillon
Branches: MAIN
CVS tags: HEAD, DragonFly_1_0_REL, DragonFly_1_0_RC1, DragonFly_1_0A_REL
Device layer rollup commit.

* cdevsw_add() is now required.  cdevsw_add() and cdevsw_remove() may specify
  a mask/match indicating the range of supported minor numbers.  Multiple
  cdevsw_add()'s using the same major number, but distinctly different
  ranges, may be issued.  All devices that failed to call cdevsw_add() before
  now do.

* cdevsw_remove() now automatically marks all devices within its supported
  range as being destroyed.

* vnode->v_rdev is no longer resolved when the vnode is created.  Instead,
  only v_udev (a newly added field) is resolved.  v_rdev is resolved when
  the vnode is opened and cleared on the last close.

* A great deal of code was making rather dubious assumptions with regards
  to the validity of devices associated with vnodes, primarily due to
  the persistence of a device structure due to being indexed by (major, minor)
  instead of by (cdevsw, major, minor).  In particular, if you run a program
  which connects to a USB device and then you pull the USB device and plug
  it back in, the vnode subsystem will continue to believe that the device
  is open when, in fact, it isn't (because it was destroyed and recreated).

  In particular, note that all the VFS mount procedures now check devices
  via v_udev instead of v_rdev prior to calling VOP_OPEN(), since v_rdev
  is NULL prior to the first open.

* The disk layer's device interaction has been rewritten.  The disk layer
  (i.e. the slice and disklabel management layer) no longer overloads
  its data onto the device structure representing the underlying physical
  disk.  Instead, the disk layer uses the new cdevsw_add() functionality
  to register its own cdevsw using the underlying device's major number,
  and simply does NOT register the underlying device's cdevsw.  No
  confusion is created because the device hash is now based on
  (cdevsw,major,minor) rather then (major,minor).

  NOTE: This also means that underlying raw disk devices may use the entire
  device minor number instead of having to reserve the bits used by the disk
  layer, and also means that can we (theoretically) stack a fully
  disklabel-supported 'disk' on top of any block device.

* The new reference counting scheme prevents this by associating a device
  with a cdevsw and disconnecting the device from its cdevsw when the cdevsw
  is removed.  Additionally, all udev2dev() lookups run through the cdevsw
  mask/match and only successfully find devices still associated with an
  active cdevsw.

* Major work on MFS:  MFS no longer shortcuts vnode and device creation.  It
  now creates a real vnode and a real device and implements real open and
  close VOPs.  Additionally, due to the disk layer changes, MFS is no longer
  limited to 255 mounts.  The new limit is 16 million.  Since MFS creates a
  real device node, mount_mfs will now create a real /dev/mfs<PID> device
  that can be read from userland (e.g. so you can dump an MFS filesystem).

* BUF AND DEVICE STRATEGY changes.  The struct buf contains a b_dev field.
  In order to properly handle stacked devices we now require that the b_dev
  field be initialized before the device strategy routine is called.  This
  required some additional work in various VFS implementations.  To enforce
  this requirement, biodone() now sets b_dev to NODEV.  The new disk layer
  will adjust b_dev before forwarding a request to the actual physical
  device.

* A bug in the ISO CD boot sequence which resulted in a panic has been fixed.

Testing by: lots of people, but David Rhodus found the most aggregious bugs.

    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 $
   29:  * $DragonFly: src/sys/dev/raid/ips/ips.h,v 1.2 2004/05/19 22:52:47 dillon Exp $
   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: 
  209: struct 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:  */
  270: struct ips_softc;
  271: 
  272: typedef 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: 
  282: typedef 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: 
  293: typedef 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: 
  303: typedef 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: 
  313: typedef 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: 
  323: typedef 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: 
  339: typedef 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: 
  345: typedef 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: 
  360: typedef struct {
  361: 	u_int32_t	addr;
  362: 	u_int32_t	len;
  363: } ips_sg_element_t;
  364: 
  365: typedef 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: 
  373: typedef 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: 
  380: typedef 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: 
  405: typedef 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: 
  413: typedef 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 */
  424: typedef 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: 
  441: typedef 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: 
  447: typedef 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;
  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 */
  486: extern 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 */
  489: extern void ipsd_finish(struct bio *iobuf);
  490: 
  491: /* function defines from ips_commands.c */
  492: extern int ips_flush_cache(ips_softc_t *sc);
  493: extern void ips_start_io_request(ips_softc_t *sc, struct bio *iobuf);
  494: extern int ips_get_drive_info(ips_softc_t *sc);
  495: extern int ips_get_adapter_info(ips_softc_t *sc);
  496: extern int ips_ffdc_reset(ips_softc_t *sc);
  497: extern int ips_update_nvram(ips_softc_t *sc);
  498: extern int ips_clear_adapter(ips_softc_t *sc);
  499: 
  500: /* function defines from ips.c */
  501: extern int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *),
  502: 				void *data, unsigned long flags);
  503: extern void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command);
  504: extern int ips_adapter_init(ips_softc_t *sc);
  505: extern int ips_morpheus_reinit(ips_softc_t *sc, int force);
  506: extern int ips_adapter_free(ips_softc_t *sc);
  507: extern void ips_morpheus_intr(void *sc);
  508: extern void ips_issue_morpheus_cmd(ips_command_t *command);
  509: extern int ips_copperhead_reinit(ips_softc_t *sc, int force);
  510: extern void ips_copperhead_intr(void *sc);
  511: extern void ips_issue_copperhead_cmd(ips_command_t *command);
  512: 
  513: #define IPS_CDEV_MAJOR 175
  514: #define IPSD_CDEV_MAJOR 176