1 /*
2 * Copyright (C) 1995, HD Associates, Inc.
3 * PO Box 276
4 * Pepperell, MA 01463
5 * 508 433 5266
6 * dufault@hda.com
7 *
8 * This code is contributed to the University of California at Berkeley:
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * $FreeBSD: src/sys/scsi/scsi_driver.c,v 1.18.2.1 1999/09/05 08:21:42 peter Exp $
39 *
40 */
41
42 #include "opt_scsi.h"
43
44 #include <sys/types.h>
45 #include <sys/errno.h>
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/buf.h>
49 #include <sys/malloc.h>
50 #include <sys/fcntl.h>
51
52 #include <scsi/scsi_all.h>
53 #include <scsi/scsiconf.h>
54 #include <scsi/scsi_driver.h>
55
56 #define GETUNIT(DEVICE, DEV) \
57 ((DEVICE)->getunit) ? (*(DEVICE)->getunit)((DEV)) \
58 : (minor((DEV)) & ~SCSI_CONTROL_MASK)
59
60 int
61 scsi_goaway(int force) /* XXX should do a lot more */
62 {
63 return 0;
64 }
65
66 /* scsi_device_attach: Attach a SCSI device. This routine will
67 * print out the device address, what it is, then call the type
68 * attach function and when that returns print a newline. If the
69 * type attach will make LOT's of noise it should print a leading
70 * newline and then the address using sc_print_addr. See "sd.c".
71 */
72 int scsi_device_attach(struct scsi_link *sc_link)
73 {
74 errval errcode;
75 dev_t dev;
76 struct scsi_device *device = sc_link->device;
77
78 if (bootverbose)
79 sc_link->flags |= SDEV_BOOTVERBOSE;
80
81 SC_DEBUG(sc_link, SDEV_DB2,
82 ("%s%dattach: ", device->name, sc_link->dev_unit));
83
84 sc_print_start(sc_link);
85 printf("%s ", device->desc);
86
87 dev = scsi_dev_lookup(device->open);
88
89 sc_link->dev = (device->setunit ?
90 (*device->setunit)(dev, sc_link->dev_unit) :
91 makedev(major(dev), sc_link->dev_unit) );
92
93 errcode = (device->attach) ? (*(device->attach))(sc_link) : 0;
94
95 sc_print_finish();
96 printf("\n");
97
98 if (errcode == 0)
99 sc_link->flags |= device->link_flags;
100
101 return errcode;
102 }
103
104 int
105 scsi_open(dev_t dev, int flags, int fmt, struct proc *p,
106 struct scsi_device *device)
107 {
108 errval errcode;
109 u_int32_t unit;
110 struct scsi_link *sc_link;
111
112 if (device == 0)
113 return ENXIO;
114
115 unit = GETUNIT(device, dev);
116 sc_link = SCSI_LINK(device, unit);
117
118 /*
119 * Check the unit is legal
120 */
121 if (sc_link == 0 || (sc_link->sd == 0 && !(sc_link->flags & SDEV_UK)))
122 return ENXIO;
123
124 /* If it is a "once only" device that is already open return EBUSY.
125 */
126 if ((sc_link->flags & SDEV_ONCE_ONLY) && (sc_link->flags & SDEV_IS_OPEN))
127 return EBUSY;
128
129 /* For the control device (user ioctl's only) don't call the open
130 * entry.
131 */
132 if (SCSI_CONTROL(dev) || (device->dev_open == 0))
133 {
134 scsi_test_unit_ready(sc_link, SCSI_SILENT);
135 errcode = 0;
136 }
137 else
138 errcode = (*device->dev_open)(dev, flags, fmt, p, sc_link);
139
140 if (!errcode ) sc_link->flags |= SDEV_IS_OPEN;
141
142 SC_DEBUG(sc_link, SDEV_DB1, ("%sopen: dev=0x%lx (unit %ld) result %d\n",
143 device->name, dev, unit, errcode));
144
145 return errcode;
146 }
147
148 int
149 scsi_close(dev_t dev, int flags, int fmt, struct proc *p,
150 struct scsi_device *device)
151 {
152 errval errcode;
153 struct scsi_link *sc_link = SCSI_LINK(device, GETUNIT(device, dev));
154
155 SC_DEBUG(sc_link, SDEV_DB1, ("%sclose: Closing device\n", device->name));
156
157 if (SCSI_CONTROL(dev) || (device->dev_close == 0))
158 errcode = 0;
159 else
160 errcode = (*device->dev_close)(dev, flags, fmt, p, sc_link);
161
162 sc_link->flags &= ~SDEV_IS_OPEN;
163
164 return errcode;
165 }
166
167 int
168 scsi_ioctl(dev_t dev, u_int32_t cmd, caddr_t arg, int flags, struct proc *p,
169 struct scsi_device *device)
170 {
171 errval errcode;
172 struct scsi_link *sc_link = SCSI_LINK(device, GETUNIT(device, dev));
173
174 if (SCSI_CONTROL(dev) || (device->dev_ioctl == 0))
175 errcode = scsi_do_ioctl(dev, cmd, arg, flags, p, sc_link);
176 else
177 errcode = (*device->dev_ioctl)(dev, cmd, arg, flags, p, sc_link);
178
179 return errcode;
180 }
181
182 void
183 scsi_minphys(struct buf *bp, struct scsi_device *device)
184 {
185 struct scsi_link *sc_link = SCSI_LINK(device, GETUNIT(device, bp->b_dev));
186 (*sc_link->adapter->scsi_minphys)(bp);
187 }
188
189 void
190 scsi_strategy(struct buf *bp, struct scsi_device *device)
191 {
192 u_int32_t unit = GETUNIT(device, bp->b_dev);
193 struct scsi_link *sc_link = SCSI_LINK(device, unit);
194
195 SC_DEBUG(sc_link, SDEV_DB2, ("\n%sstrategy ", device->name));
196 SC_DEBUG(sc_link, SDEV_DB1, ("%ld bytes @ blk%ld\n",
197 bp->b_bcount, bp->b_blkno));
198
199 if (SCSI_CONTROL(bp->b_dev) || (device->dev_strategy == 0))
200 {
201 bp->b_resid = bp->b_bcount;
202 bp->b_error = EIO;
203 bp->b_flags |= B_ERROR;
204 biodone(bp);
205 }
206 else
207 {
208 bp->b_resid = 0;
209 bp->b_error = 0;
210
211 if (bp->b_bcount == 0)
212 biodone(bp);
213 else
214 {
215 (*sc_link->adapter->scsi_minphys)(bp);
216 (*device->dev_strategy)(bp, sc_link);
217 }
218 }
219 }
Cache object: 8e63a81727caf07b1cc8a913e4766974
|