summaryrefslogtreecommitdiffstats
path: root/sys/scsi/uk.c
blob: 149e2dfd4da63a203eea38b26603f7b6d6d0214c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* 
 * Dummy driver for a device we can't identify.
 * by Julian Elischer (julian@tfs.com)
 *
 *      $Id: uk.c,v 1.2 1993/11/25 01:37:35 wollman Exp $
 */

#include <sys/param.h>
#include "systm.h"
#include <sys/errno.h>
#include <sys/ioctl.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#define NUK 16

/*
 * This driver is so simple it uses all the default services
 */
struct scsi_device uk_switch =
{
    NULL,
    NULL,
    NULL,
    NULL,
    "uk",
    0,
    0, 0
};

struct uk_data {
	u_int32 flags;
	struct scsi_link *sc_link;	/* all the inter level info */
} uk_data[NUK];

#define UK_KNOWN	0x02

static u_int32 next_uk_unit = 0;

/*
 * The routine called by the low level scsi routine when it discovers
 * a device suitable for this driver.
 */
errval 
ukattach(sc_link)
	struct scsi_link *sc_link;
{
	u_int32 unit, i, stat;
	unsigned char *tbl;

	SC_DEBUG(sc_link, SDEV_DB2, ("ukattach: "));
	/*
	 * Check we have the resources for another drive
	 */
	unit = next_uk_unit++;
	if (unit >= NUK) {
		printf("Too many unknown devices..(%d > %d) reconfigure kernel\n",
				(unit + 1), NUK);
		return (0);
	}
	/*
	 * Store information needed to contact our base driver
	 */
	uk_data[unit].sc_link = sc_link;
	sc_link->device = &uk_switch;
	sc_link->dev_unit = unit;

	printf("uk%d: unknown device\n", unit);
	uk_data[unit].flags = UK_KNOWN;

	return 1;		/* XXX ??? */

}

/*
 *    open the device.
 */
errval 
ukopen(dev)
	dev_t dev;
{
	errval  errcode = 0;
	u_int32 unit, mode;
	struct scsi_link *sc_link;
	unit = minor(dev);

	/*
	 * Check the unit is legal 
	 */
	if (unit >= NUK) {
		printf("uk%d: uk %d  > %d\n", unit, unit, NUK);
		return ENXIO;
	}

	/*
	 * Make sure the device has been initialised
	 */
	if((uk_data[unit].flags & UK_KNOWN) == 0) {
		printf("uk%d: not set up\n", unit);
		return ENXIO;
	}
		
	/*
	 * Only allow one at a time
	 */
	sc_link = uk_data[unit].sc_link;
	if (sc_link->flags & SDEV_OPEN) {
		printf("uk%d: already open\n", unit);
		return ENXIO;
	}
	sc_link->flags |= SDEV_OPEN;
	SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n"
		,dev, unit, NUK));
	/*
	 * Catch any unit attention errors.
	 */
	return 0;
}

/*
 * close the device.. only called if we are the LAST
 * occurence of an open device
 */
errval 
ukclose(dev)
	dev_t dev;
{
	unsigned char unit = 0, mode; /* XXX !!! XXX FIXME!!! 0??? */
	struct scsi_link *sc_link;

	sc_link = uk_data[unit].sc_link;

	SC_DEBUG(sc_link, SDEV_DB1, ("Closing device"));
	sc_link->flags &= ~SDEV_OPEN;
	return (0);
}

/*
 * Perform special action on behalf of the user
 * Only does generic scsi ioctls.
 */
errval 
ukioctl(dev, cmd, arg, mode)
	dev_t   dev;
	u_int32 cmd;
	caddr_t arg;
	int mode;
{
	unsigned char unit;
	struct scsi_link *sc_link;

	/*
	 * Find the device that the user is talking about
	 */
	unit = minor(dev);
	sc_link = uk_data[unit].sc_link;
	return(scsi_do_ioctl(sc_link,cmd,arg,mode));
}

OpenPOWER on IntegriCloud