1 2 /* 3 * Dummy driver for a device we can't identify. 4 * by Julian Elischer (julian@tfs.com) 5 * 6 * $Id: uk.c,v 1.1 1993/11/24 04:52:53 mycroft Exp $ 7 */ 8 9 10 #include <sys/types.h> 11 #include <sys/param.h> 12 #include <sys/errno.h> 13 #include <sys/ioctl.h> 14 #include <scsi/scsi_all.h> 15 #include <scsi/scsiconf.h> 16 #define NUK 16 17 18 /* 19 * This driver is so simple it uses all the default services 20 */ 21 struct scsi_device uk_switch = 22 { 23 NULL, 24 NULL, 25 NULL, 26 NULL, 27 "uk", 28 0, 29 0, 0 30 }; 31 32 struct uk_data { 33 u_int32 flags; 34 struct scsi_link *sc_link; /* all the inter level info */ 35 } uk_data[NUK]; 36 37 #define UK_KNOWN 0x02 38 39 static u_int32 next_uk_unit = 0; 40 41 /* 42 * The routine called by the low level scsi routine when it discovers 43 * a device suitable for this driver. 44 */ 45 errval 46 ukattach(sc_link) 47 struct scsi_link *sc_link; 48 { 49 u_int32 unit, i, stat; 50 unsigned char *tbl; 51 52 SC_DEBUG(sc_link, SDEV_DB2, ("ukattach: ")); 53 /* 54 * Check we have the resources for another drive 55 */ 56 unit = next_uk_unit++; 57 if (unit >= NUK) { 58 printf("Too many unknown devices..(%d > %d) reconfigure kernel\n", 59 (unit + 1), NUK); 60 return (0); 61 } 62 /* 63 * Store information needed to contact our base driver 64 */ 65 uk_data[unit].sc_link = sc_link; 66 sc_link->device = &uk_switch; 67 sc_link->dev_unit = unit; 68 69 printf("uk%d: unknown device\n", unit); 70 uk_data[unit].flags = UK_KNOWN; 71 72 return; 73 74 } 75 76 /* 77 * open the device. 78 */ 79 errval 80 ukopen(dev) 81 { 82 errval errcode = 0; 83 u_int32 unit, mode; 84 struct scsi_link *sc_link; 85 unit = minor(dev); 86 87 /* 88 * Check the unit is legal 89 */ 90 if (unit >= NUK) { 91 printf("uk%d: uk %d > %d\n", unit, unit, NUK); 92 return ENXIO; 93 } 94 95 /* 96 * Make sure the device has been initialised 97 */ 98 if((uk_data[unit].flags & UK_KNOWN) == 0) { 99 printf("uk%d: not set up\n", unit); 100 return ENXIO; 101 } 102 103 /* 104 * Only allow one at a time 105 */ 106 sc_link = uk_data[unit].sc_link; 107 if (sc_link->flags & SDEV_OPEN) { 108 printf("uk%d: already open\n", unit); 109 return ENXIO; 110 } 111 sc_link->flags |= SDEV_OPEN; 112 SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n" 113 ,dev, unit, NUK)); 114 /* 115 * Catch any unit attention errors. 116 */ 117 return 0; 118 } 119 120 /* 121 * close the device.. only called if we are the LAST 122 * occurence of an open device 123 */ 124 errval 125 ukclose(dev) 126 { 127 unsigned char unit, mode; 128 struct scsi_link *sc_link; 129 130 sc_link = uk_data[unit].sc_link; 131 132 SC_DEBUG(sc_link, SDEV_DB1, ("Closing device")); 133 sc_link->flags &= ~SDEV_OPEN; 134 return (0); 135 } 136 137 /* 138 * Perform special action on behalf of the user 139 * Only does generic scsi ioctls. 140 */ 141 errval 142 ukioctl(dev, cmd, arg, mode) 143 dev_t dev; 144 u_int32 cmd; 145 caddr_t arg; 146 { 147 unsigned char unit; 148 struct scsi_link *sc_link; 149 150 /* 151 * Find the device that the user is talking about 152 */ 153 unit = minor(dev); 154 sc_link = uk_data[unit].sc_link; 155 return(scsi_do_ioctl(sc_link,cmd,arg,mode)); 156 } 157 158