|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * This code is derived from software contributed to Berkeley by ! 6: * Chris Torek. ! 7: * ! 8: * Redistribution is only permitted until one year after the first shipment ! 9: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and ! 10: * binary forms are permitted provided that: (1) source distributions retain ! 11: * this entire copyright notice and comment, and (2) distributions including ! 12: * binaries display the following acknowledgement: This product includes ! 13: * software developed by the University of California, Berkeley and its ! 14: * contributors'' in the documentation or other materials provided with the ! 15: * distribution and in all advertising materials mentioning features or use ! 16: * of this software. Neither the name of the University nor the names of ! 17: * its contributors may be used to endorse or promote products derived from ! 18: * this software without specific prior written permission. ! 19: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 20: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 21: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 22: * ! 23: * @(#)mscpvar.h 7.3 (Berkeley) 6/28/90 ! 24: */ ! 25: ! 26: /* ! 27: * MSCP generic driver configuration ! 28: */ ! 29: ! 30: /* ! 31: * Enabling MSCP_PARANOIA makes the response code perform various checks ! 32: * on the hardware. (Right now it verifies only the buffer pointer in ! 33: * mscp_cmdref.) ! 34: * ! 35: * Enabling AVOID_EMULEX_BUG selects an alternative method of identifying ! 36: * transfers in progress, which gets around a rather peculiar bug in the ! 37: * SC41/MS. Enabling MSCP_PARANOIA instead should work, but will cause ! 38: * `extra' Unibus resets. ! 39: * ! 40: * Either of these flags can simply be included as an `options' line in ! 41: * your configuration file. ! 42: */ ! 43: ! 44: /* #define MSCP_PARANOIA */ ! 45: /* #define AVOID_EMULEX_BUG */ ! 46: ! 47: /* ! 48: * Per driver information. ! 49: * ! 50: * md_ndpc sets the maximum unit number allowed in response packets. ! 51: * md_nunits is the number of drives attached to all controllers. ! 52: * md_unitshift is the divisor for converting a minor device number ! 53: * to a unit index for the device queues in md_utab. ! 54: * ! 55: * The routines are called from the generic response dispatcher. ! 56: * THE FOLLOWING IS OUT OF DATE ! 57: * The first three (dgram, ctlrdone, and unconf) get passed a pointer ! 58: * to the uba_ctlr and to the packet; the rest get a pointer to the ! 59: * uba_device and to the packet (`um, mp' and `ui, mp' respectively). ! 60: * The routines unconf, online, gotstatus, and ioerr are functions ! 61: * and should return one of the values given below. In addition, ! 62: * the ioerr and bb routines get a third argument, `bp': a pointer ! 63: * to the buffer describing the transfer in error. ! 64: * END OUT OF DATE ! 65: */ ! 66: struct mscp_driver { ! 67: int md_ndpc; /* number of drives per ctlr */ ! 68: int md_nunits; /* total number drives (all ctlrs) */ ! 69: int md_unitshift; /* device number to unit: >> count */ ! 70: struct buf *md_utab; /* pointer to device queues */ ! 71: struct disklabel *md_lab; /* pointer to devicee disklabels */ ! 72: struct uba_device **md_dinfo; /* pointer to device info */ ! 73: int (*md_dgram)(); /* error datagram */ ! 74: int (*md_ctlrdone)(); /* controller operation complete */ ! 75: int (*md_unconf)(); /* response from unconfigured drive */ ! 76: int (*md_iodone)(); /* normal I/O is done */ ! 77: int (*md_online)(); /* drive on line */ ! 78: int (*md_gotstatus)(); /* got unit status */ ! 79: int (*md_replace)(); /* replace done */ ! 80: int (*md_ioerr)(); /* read or write failed */ ! 81: int (*md_bb)(); /* B_BAD io done */ ! 82: char *md_mname; /* name of controllers */ ! 83: char *md_dname; /* name of drives */ ! 84: }; ! 85: ! 86: /* ! 87: * Return values from functions. ! 88: * MSCP_RESTARTED is peculiar to I/O errors. ! 89: */ ! 90: #define MSCP_DONE 0 /* all ok */ ! 91: #define MSCP_FAILED 1 /* no go */ ! 92: #define MSCP_RESTARTED 2 /* transfer restarted */ ! 93: ! 94: /* ! 95: * Ring information, per ring (one each for commands and responses). ! 96: */ ! 97: struct mscp_ri { ! 98: int mri_size; /* ring size */ ! 99: int mri_next; /* next (expected|free) */ ! 100: long *mri_desc; /* base address of descriptors */ ! 101: struct mscp *mri_ring; /* base address of packets */ ! 102: }; ! 103: ! 104: /* ! 105: * Per device information. ! 106: * ! 107: * mi_ip is a pointer to the inverting pointers (things that get `ui's ! 108: * given unit numbers) FOR THIS CONTROLLER (NOT the whole set!). ! 109: * ! 110: * mi_wtab holds a queue of those transfers that were started but have ! 111: * not yet finished. Other Unibus drivers do not need this as they hand ! 112: * out requests one at a time. MSCP devices, however, take a slew of ! 113: * requests and pick their own order to execute them. This means that ! 114: * we have to have a place to move transfers that were given to the ! 115: * controller, so we can tell those apart from those that have not yet ! 116: * been handed out; mi_wtab is that place. ! 117: */ ! 118: struct mscp_info { ! 119: struct mscp_driver *mi_md; /* pointer to driver info */ ! 120: int mi_ctlr; /* controller index */ ! 121: struct buf *mi_tab; /* pointer to ctlr's drive queue */ ! 122: struct uba_device **mi_ip; /* pointer to inverting pointers */ ! 123: struct mscp_ri mi_cmd; /* MSCP command ring info */ ! 124: struct mscp_ri mi_rsp; /* MSCP response ring info */ ! 125: short mi_credits; /* transfer credits */ ! 126: char mi_wantcmd; /* waiting for command packet */ ! 127: char mi_wantcredits; /* waiting for transfer credits */ ! 128: struct buf mi_wtab; /* transfer wait queue */ ! 129: #ifdef AVOID_EMULEX_BUG ! 130: #define AEB_MAX_BP 32 /* max pend xfers (power of 2) XXX */ ! 131: struct buf *mi_bp[AEB_MAX_BP]; /* xfer no. to buffer */ ! 132: u_int mi_nextbp; /* generates unique xfer no's */ ! 133: int mi_ok; /* for error rate statistics */ ! 134: #endif AVOID_EMULEX_BUG ! 135: }; ! 136: ! 137: /* ! 138: * We have run out of credits when mi_credits is <= MSCP_MINCREDITS. ! 139: * It is still possible to issue one command in this case, but it must ! 140: * not be a data transfer. E.g., `get command status' or `abort command' ! 141: * is legal, while `read' is not. ! 142: */ ! 143: #define MSCP_MINCREDITS 1 ! 144: ! 145: /* ! 146: * Flags for mscp_getcp(). ! 147: */ ! 148: #define MSCP_WAIT 1 ! 149: #define MSCP_DONTWAIT 0 ! 150: ! 151: struct mscp *mscp_getcp(); /* get a command packet */ ! 152: ! 153: /* ! 154: * Unit flags ! 155: */ ! 156: #define UNIT_ONLINE 0x01 /* drive is on line */ ! 157: #define UNIT_HAVESTATUS 0x02 /* got unit status */ ! 158: #define UNIT_REQUEUE 0x04 /* requeue after response */ ! 159: ! 160: /* ! 161: * Handle a command ring transition: wake up sleepers for command packets. ! 162: * This is too simple to bother with a function call. ! 163: */ ! 164: #define MSCP_DOCMD(mi) { \ ! 165: if ((mi)->mi_wantcmd) { \ ! 166: (mi)->mi_wantcmd = 0; \ ! 167: wakeup((caddr_t) &(mi)->mi_wantcmd); \ ! 168: } \ ! 169: } ! 170: ! 171: /* ! 172: * The following macro appends a buffer to a drive queue or a drive to ! 173: * a controller queue, given the name of the forward link. Use as ! 174: * `APPEND(dp, &um->um_tab, b_forw)' or `APPEND(bp, dp, av_forw)', ! 175: * where `bp' is a transfer request, `dp' is a drive queue, and `um_tab' ! 176: * is a controller queue. (That is, the forward link for controller ! 177: * queues is `b_forw'; for drive queues, it is `av_forw'.) ! 178: */ ! 179: #define APPEND(bp, queue, link) { \ ! 180: (bp)->link = NULL; \ ! 181: if ((queue)->b_actf == NULL) \ ! 182: (queue)->b_actf = (bp); \ ! 183: else \ ! 184: (queue)->b_actl->link = (bp); \ ! 185: (queue)->b_actl = (bp); \ ! 186: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.