Deleted Added
full compact
cam_periph.c (40603) cam_periph.c (41877)
1/*
2 * Common functions for CAM "type" (peripheral) drivers.
3 *
4 * Copyright (c) 1997, 1998 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification, immediately at the beginning of the file.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*
2 * Common functions for CAM "type" (peripheral) drivers.
3 *
4 * Copyright (c) 1997, 1998 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions, and the following disclaimer,
13 * without modification, immediately at the beginning of the file.
14 * 2. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Id: cam_periph.c,v 1.5 1998/10/15 17:46:18 ken Exp $
29 * $Id: cam_periph.c,v 1.6 1998/10/22 22:16:48 ken Exp $
30 */
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/types.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37#include <sys/buf.h>
38#include <sys/proc.h>
39#include <sys/devicestat.h>
40#include <vm/vm.h>
41#include <vm/vm_extern.h>
42
43#include <cam/cam.h>
44#include <cam/cam_conf.h>
45#include <cam/cam_ccb.h>
46#include <cam/cam_xpt_periph.h>
47#include <cam/cam_periph.h>
48#include <cam/cam_debug.h>
49
50#include <cam/scsi/scsi_all.h>
51#include <cam/scsi/scsi_message.h>
52#include <cam/scsi/scsi_da.h>
53#include <cam/scsi/scsi_pass.h>
54
55static u_int camperiphnextunit(struct periph_driver *p_drv,
56 u_int newunit, int wired);
57static u_int camperiphunit(struct periph_driver *p_drv,
58 path_id_t path_id_t,
59 target_id_t target, lun_id_t lun);
60static void camperiphdone(struct cam_periph *periph,
61 union ccb *done_ccb);
62static void camperiphfree(struct cam_periph *periph);
63
64cam_status
65cam_periph_alloc(periph_ctor_t *periph_ctor,
66 periph_oninv_t *periph_oninvalidate,
67 periph_dtor_t *periph_dtor, periph_start_t *periph_start,
68 char *name, cam_periph_type type, struct cam_path *path,
69 ac_callback_t *ac_callback, ac_code code, void *arg)
70{
71 struct periph_driver **p_drv;
72 struct cam_periph *periph;
73 struct cam_periph *cur_periph;
74 path_id_t path_id;
75 target_id_t target_id;
76 lun_id_t lun_id;
77 cam_status status;
78 u_int init_level;
79 int s;
80
81 init_level = 0;
82 /*
83 * Handle Hot-Plug scenarios. If there is already a peripheral
84 * of our type assigned to this path, we are likely waiting for
85 * final close on an old, invalidated, peripheral. If this is
86 * the case, queue up a deferred call to the peripheral's async
87 * handler. If it looks like a mistaken re-alloation, complain.
88 */
89 if ((periph = cam_periph_find(path, name)) != NULL) {
90
91 if ((periph->flags & CAM_PERIPH_INVALID) != 0
92 && (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) == 0) {
93 periph->flags |= CAM_PERIPH_NEW_DEV_FOUND;
94 periph->deferred_callback = ac_callback;
95 periph->deferred_ac = code;
96 return (CAM_REQ_INPROG);
97 } else {
98 printf("cam_periph_alloc: attempt to re-allocate "
99 "valid device %s%d rejected\n",
100 periph->periph_name, periph->unit_number);
101 }
102 return (CAM_REQ_INVALID);
103 }
104
105 periph = (struct cam_periph *)malloc(sizeof(*periph), M_DEVBUF,
106 M_NOWAIT);
107
108 if (periph == NULL)
109 return (CAM_RESRC_UNAVAIL);
110
111 init_level++;
112
113 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
114 *p_drv != NULL; p_drv++) {
115 if (strcmp((*p_drv)->driver_name, name) == 0)
116 break;
117 }
118
119 path_id = xpt_path_path_id(path);
120 target_id = xpt_path_target_id(path);
121 lun_id = xpt_path_lun_id(path);
122 bzero(periph, sizeof(*periph));
123 cam_init_pinfo(&periph->pinfo);
124 periph->periph_start = periph_start;
125 periph->periph_dtor = periph_dtor;
126 periph->periph_oninval = periph_oninvalidate;
127 periph->type = type;
128 periph->periph_name = name;
129 periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id);
130 periph->immediate_priority = CAM_PRIORITY_NONE;
131 periph->refcount = 0;
132 SLIST_INIT(&periph->ccb_list);
133 status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
134 if (status != CAM_REQ_CMP)
135 goto failure;
136
137 periph->path = path;
138 init_level++;
139
140 status = xpt_add_periph(periph);
141
142 if (status != CAM_REQ_CMP)
143 goto failure;
144
145 s = splsoftcam();
146 cur_periph = TAILQ_FIRST(&(*p_drv)->units);
147 while (cur_periph != NULL
148 && cur_periph->unit_number < periph->unit_number)
149 cur_periph = TAILQ_NEXT(cur_periph, unit_links);
150
151 if (cur_periph != NULL)
152 TAILQ_INSERT_BEFORE(cur_periph, periph, unit_links);
153 else {
154 TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links);
155 (*p_drv)->generation++;
156 }
157
158 splx(s);
159
160 init_level++;
161
162 status = periph_ctor(periph, arg);
163
164 if (status == CAM_REQ_CMP)
165 init_level++;
166
167failure:
168 switch (init_level) {
169 case 4:
170 /* Initialized successfully */
171 break;
172 case 3:
173 s = splsoftcam();
174 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
175 splx(s);
176 xpt_remove_periph(periph);
177 case 2:
178 xpt_free_path(periph->path);
179 case 1:
180 free(periph, M_DEVBUF);
181 case 0:
182 /* No cleanup to perform. */
183 break;
184 default:
185 panic("cam_periph_alloc: Unkown init level");
186 }
187 return(status);
188}
189
190/*
191 * Find a peripheral structure with the specified path, target, lun,
192 * and (optionally) type. If the name is NULL, this function will return
193 * the first peripheral driver that matches the specified path.
194 */
195struct cam_periph *
196cam_periph_find(struct cam_path *path, char *name)
197{
198 struct periph_driver **p_drv;
199 struct cam_periph *periph;
200 int s;
201
202 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
203 *p_drv != NULL; p_drv++) {
204
205 if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0))
206 continue;
207
208 s = splsoftcam();
209 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
210 periph = TAILQ_NEXT(periph, unit_links)) {
211 if (xpt_path_comp(periph->path, path) == 0) {
212 splx(s);
213 return(periph);
214 }
215 }
216 splx(s);
217 if (name != NULL)
218 return(NULL);
219 }
220 return(NULL);
221}
222
223cam_status
224cam_periph_acquire(struct cam_periph *periph)
225{
226 int s;
227
228 if (periph == NULL)
229 return(CAM_REQ_CMP_ERR);
230
231 s = splsoftcam();
232 periph->refcount++;
233 splx(s);
234
235 return(CAM_REQ_CMP);
236}
237
238void
239cam_periph_release(struct cam_periph *periph)
240{
241 int s;
242
243 if (periph == NULL)
244 return;
245
246 s = splsoftcam();
247 if ((--periph->refcount == 0)
248 && (periph->flags & CAM_PERIPH_INVALID)) {
249 camperiphfree(periph);
250 }
251 splx(s);
252
253}
254
255/*
256 * Look for the next unit number that is not currently in use for this
257 * peripheral type starting at "newunit". Also exclude unit numbers that
258 * are reserved by for future "hardwiring" unless we already know that this
259 * is a potential wired device. Only assume that the device is "wired" the
260 * first time through the loop since after that we'll be looking at unit
261 * numbers that did not match a wiring entry.
262 */
263static u_int
264camperiphnextunit(struct periph_driver *p_drv, u_int newunit, int wired)
265{
266 struct cam_periph *periph;
267 struct cam_periph_config *periph_conf;
268 char *periph_name;
269 int s;
270
271 s = splsoftcam();
272 periph_name = p_drv->driver_name;
273 for (;;newunit++) {
274
275 for (periph = TAILQ_FIRST(&p_drv->units);
276 periph != NULL && periph->unit_number != newunit;
277 periph = TAILQ_NEXT(periph, unit_links))
278 ;
279
280 if (periph != NULL && periph->unit_number == newunit) {
281 if (wired != 0) {
282 xpt_print_path(periph->path);
283 printf("Duplicate Wired Device entry!\n");
284 xpt_print_path(periph->path);
285 printf("Second device will not be wired\n");
286 wired = 0;
287 }
288 continue;
289 }
290
291 for (periph_conf = cam_pinit;
292 wired == 0 && periph_conf->periph_name != NULL;
293 periph_conf++) {
294
295 /*
296 * Don't match entries like "da 4" as a wired down
297 * device, but do match entries like "da 4 target 5"
298 * or even "da 4 scbus 1".
299 */
300 if (IS_SPECIFIED(periph_conf->periph_unit)
301 && (!strcmp(periph_name, periph_conf->periph_name))
302 && (IS_SPECIFIED(periph_conf->target)
303 || IS_SPECIFIED(periph_conf->pathid))
304 && (newunit == periph_conf->periph_unit))
305 break;
306 }
307
308 if (wired != 0 || periph_conf->periph_name == NULL)
309 break;
310 }
311 splx(s);
312 return (newunit);
313}
314
315static u_int
316camperiphunit(struct periph_driver *p_drv, path_id_t pathid,
317 target_id_t target, lun_id_t lun)
318{
319 struct cam_periph_config *periph_conf;
320 u_int unit;
321 int hit;
322
323 unit = 0;
324 hit = 0;
325
326 for (periph_conf = cam_pinit;
327 periph_conf->periph_name != NULL;
328 periph_conf++, hit = 0) {
329
330 if (!strcmp(p_drv->driver_name, periph_conf->periph_name)
331 && IS_SPECIFIED(periph_conf->periph_unit)) {
332
333 if (IS_SPECIFIED(periph_conf->pathid)) {
334
335 if (pathid != periph_conf->pathid)
336 continue;
337 hit++;
338 }
339
340 if (IS_SPECIFIED(periph_conf->target)) {
341
342 if (target != periph_conf->target)
343 continue;
344 hit++;
345 }
346
347 if (IS_SPECIFIED(periph_conf->lun)) {
348
349 if (lun != periph_conf->lun)
350 continue;
351 hit++;
352 }
353
354 if (hit != 0) {
355 unit = periph_conf->periph_unit;
356 break;
357 }
358 }
359 }
360
361 /*
362 * Either start from 0 looking for the next unit or from
363 * the unit number given in the periph_conf. This way,
364 * if we have wildcard matches, we don't return the same
365 * unit number twice.
366 */
367 unit = camperiphnextunit(p_drv, unit, /*wired*/hit);
368
369 return (unit);
370}
371
372void
373cam_periph_invalidate(struct cam_periph *periph)
374{
375 int s;
376
377 s = splsoftcam();
378 /*
379 * We only call this routine the first time a peripheral is
380 * invalidated. The oninvalidate() routine is always called at
381 * splsoftcam().
382 */
383 if (((periph->flags & CAM_PERIPH_INVALID) == 0)
384 && (periph->periph_oninval != NULL))
385 periph->periph_oninval(periph);
386
387 periph->flags |= CAM_PERIPH_INVALID;
388 periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
389
390 if (periph->refcount == 0)
391 camperiphfree(periph);
392 else if (periph->refcount < 0)
393 printf("cam_invalidate_periph: refcount < 0!!\n");
394 splx(s);
395}
396
397static void
398camperiphfree(struct cam_periph *periph)
399{
400 int s;
401 struct periph_driver **p_drv;
402
403 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
404 *p_drv != NULL; p_drv++) {
405 if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0)
406 break;
407 }
408
409 if (periph->periph_dtor != NULL)
410 periph->periph_dtor(periph);
411
412 s = splsoftcam();
413 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
414 (*p_drv)->generation++;
415 splx(s);
416
417 xpt_remove_periph(periph);
418
419 if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) {
420 union ccb ccb;
421 void *arg;
422
423 switch (periph->deferred_ac) {
424 case AC_FOUND_DEVICE:
425 ccb.ccb_h.func_code = XPT_GDEV_TYPE;
426 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
427 xpt_action(&ccb);
428 arg = &ccb;
429 break;
430 case AC_PATH_REGISTERED:
431 ccb.ccb_h.func_code = XPT_PATH_INQ;
432 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
433 xpt_action(&ccb);
434 arg = &ccb;
435 break;
436 default:
437 arg = NULL;
438 break;
439 }
440 periph->deferred_callback(NULL, periph->deferred_ac,
441 periph->path, arg);
442 }
443 xpt_free_path(periph->path);
444 free(periph, M_DEVBUF);
445}
446
447/*
448 * Wait interruptibly for an exclusive lock.
449 */
450int
451cam_periph_lock(struct cam_periph *periph, int priority)
452{
453 int error;
454
455 while ((periph->flags & CAM_PERIPH_LOCKED) != 0) {
456 periph->flags |= CAM_PERIPH_LOCK_WANTED;
457 if ((error = tsleep(periph, priority, "caplck", 0)) != 0)
458 return error;
459 }
460
461 if (cam_periph_acquire(periph) != CAM_REQ_CMP)
462 return(ENXIO);
463
464 periph->flags |= CAM_PERIPH_LOCKED;
465 return 0;
466}
467
468/*
469 * Unlock and wake up any waiters.
470 */
471void
472cam_periph_unlock(struct cam_periph *periph)
473{
474 periph->flags &= ~CAM_PERIPH_LOCKED;
475 if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) {
476 periph->flags &= ~CAM_PERIPH_LOCK_WANTED;
477 wakeup(periph);
478 }
479
480 cam_periph_release(periph);
481}
482
483/*
484 * Map user virtual pointers into kernel virtual address space, so we can
485 * access the memory. This won't work on physical pointers, for now it's
486 * up to the caller to check for that. (XXX KDM -- should we do that here
487 * instead?) This also only works for up to MAXPHYS memory. Since we use
488 * buffers to map stuff in and out, we're limited to the buffer size.
489 */
490int
491cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
492{
30 */
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/types.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37#include <sys/buf.h>
38#include <sys/proc.h>
39#include <sys/devicestat.h>
40#include <vm/vm.h>
41#include <vm/vm_extern.h>
42
43#include <cam/cam.h>
44#include <cam/cam_conf.h>
45#include <cam/cam_ccb.h>
46#include <cam/cam_xpt_periph.h>
47#include <cam/cam_periph.h>
48#include <cam/cam_debug.h>
49
50#include <cam/scsi/scsi_all.h>
51#include <cam/scsi/scsi_message.h>
52#include <cam/scsi/scsi_da.h>
53#include <cam/scsi/scsi_pass.h>
54
55static u_int camperiphnextunit(struct periph_driver *p_drv,
56 u_int newunit, int wired);
57static u_int camperiphunit(struct periph_driver *p_drv,
58 path_id_t path_id_t,
59 target_id_t target, lun_id_t lun);
60static void camperiphdone(struct cam_periph *periph,
61 union ccb *done_ccb);
62static void camperiphfree(struct cam_periph *periph);
63
64cam_status
65cam_periph_alloc(periph_ctor_t *periph_ctor,
66 periph_oninv_t *periph_oninvalidate,
67 periph_dtor_t *periph_dtor, periph_start_t *periph_start,
68 char *name, cam_periph_type type, struct cam_path *path,
69 ac_callback_t *ac_callback, ac_code code, void *arg)
70{
71 struct periph_driver **p_drv;
72 struct cam_periph *periph;
73 struct cam_periph *cur_periph;
74 path_id_t path_id;
75 target_id_t target_id;
76 lun_id_t lun_id;
77 cam_status status;
78 u_int init_level;
79 int s;
80
81 init_level = 0;
82 /*
83 * Handle Hot-Plug scenarios. If there is already a peripheral
84 * of our type assigned to this path, we are likely waiting for
85 * final close on an old, invalidated, peripheral. If this is
86 * the case, queue up a deferred call to the peripheral's async
87 * handler. If it looks like a mistaken re-alloation, complain.
88 */
89 if ((periph = cam_periph_find(path, name)) != NULL) {
90
91 if ((periph->flags & CAM_PERIPH_INVALID) != 0
92 && (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) == 0) {
93 periph->flags |= CAM_PERIPH_NEW_DEV_FOUND;
94 periph->deferred_callback = ac_callback;
95 periph->deferred_ac = code;
96 return (CAM_REQ_INPROG);
97 } else {
98 printf("cam_periph_alloc: attempt to re-allocate "
99 "valid device %s%d rejected\n",
100 periph->periph_name, periph->unit_number);
101 }
102 return (CAM_REQ_INVALID);
103 }
104
105 periph = (struct cam_periph *)malloc(sizeof(*periph), M_DEVBUF,
106 M_NOWAIT);
107
108 if (periph == NULL)
109 return (CAM_RESRC_UNAVAIL);
110
111 init_level++;
112
113 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
114 *p_drv != NULL; p_drv++) {
115 if (strcmp((*p_drv)->driver_name, name) == 0)
116 break;
117 }
118
119 path_id = xpt_path_path_id(path);
120 target_id = xpt_path_target_id(path);
121 lun_id = xpt_path_lun_id(path);
122 bzero(periph, sizeof(*periph));
123 cam_init_pinfo(&periph->pinfo);
124 periph->periph_start = periph_start;
125 periph->periph_dtor = periph_dtor;
126 periph->periph_oninval = periph_oninvalidate;
127 periph->type = type;
128 periph->periph_name = name;
129 periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id);
130 periph->immediate_priority = CAM_PRIORITY_NONE;
131 periph->refcount = 0;
132 SLIST_INIT(&periph->ccb_list);
133 status = xpt_create_path(&path, periph, path_id, target_id, lun_id);
134 if (status != CAM_REQ_CMP)
135 goto failure;
136
137 periph->path = path;
138 init_level++;
139
140 status = xpt_add_periph(periph);
141
142 if (status != CAM_REQ_CMP)
143 goto failure;
144
145 s = splsoftcam();
146 cur_periph = TAILQ_FIRST(&(*p_drv)->units);
147 while (cur_periph != NULL
148 && cur_periph->unit_number < periph->unit_number)
149 cur_periph = TAILQ_NEXT(cur_periph, unit_links);
150
151 if (cur_periph != NULL)
152 TAILQ_INSERT_BEFORE(cur_periph, periph, unit_links);
153 else {
154 TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links);
155 (*p_drv)->generation++;
156 }
157
158 splx(s);
159
160 init_level++;
161
162 status = periph_ctor(periph, arg);
163
164 if (status == CAM_REQ_CMP)
165 init_level++;
166
167failure:
168 switch (init_level) {
169 case 4:
170 /* Initialized successfully */
171 break;
172 case 3:
173 s = splsoftcam();
174 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
175 splx(s);
176 xpt_remove_periph(periph);
177 case 2:
178 xpt_free_path(periph->path);
179 case 1:
180 free(periph, M_DEVBUF);
181 case 0:
182 /* No cleanup to perform. */
183 break;
184 default:
185 panic("cam_periph_alloc: Unkown init level");
186 }
187 return(status);
188}
189
190/*
191 * Find a peripheral structure with the specified path, target, lun,
192 * and (optionally) type. If the name is NULL, this function will return
193 * the first peripheral driver that matches the specified path.
194 */
195struct cam_periph *
196cam_periph_find(struct cam_path *path, char *name)
197{
198 struct periph_driver **p_drv;
199 struct cam_periph *periph;
200 int s;
201
202 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
203 *p_drv != NULL; p_drv++) {
204
205 if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0))
206 continue;
207
208 s = splsoftcam();
209 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
210 periph = TAILQ_NEXT(periph, unit_links)) {
211 if (xpt_path_comp(periph->path, path) == 0) {
212 splx(s);
213 return(periph);
214 }
215 }
216 splx(s);
217 if (name != NULL)
218 return(NULL);
219 }
220 return(NULL);
221}
222
223cam_status
224cam_periph_acquire(struct cam_periph *periph)
225{
226 int s;
227
228 if (periph == NULL)
229 return(CAM_REQ_CMP_ERR);
230
231 s = splsoftcam();
232 periph->refcount++;
233 splx(s);
234
235 return(CAM_REQ_CMP);
236}
237
238void
239cam_periph_release(struct cam_periph *periph)
240{
241 int s;
242
243 if (periph == NULL)
244 return;
245
246 s = splsoftcam();
247 if ((--periph->refcount == 0)
248 && (periph->flags & CAM_PERIPH_INVALID)) {
249 camperiphfree(periph);
250 }
251 splx(s);
252
253}
254
255/*
256 * Look for the next unit number that is not currently in use for this
257 * peripheral type starting at "newunit". Also exclude unit numbers that
258 * are reserved by for future "hardwiring" unless we already know that this
259 * is a potential wired device. Only assume that the device is "wired" the
260 * first time through the loop since after that we'll be looking at unit
261 * numbers that did not match a wiring entry.
262 */
263static u_int
264camperiphnextunit(struct periph_driver *p_drv, u_int newunit, int wired)
265{
266 struct cam_periph *periph;
267 struct cam_periph_config *periph_conf;
268 char *periph_name;
269 int s;
270
271 s = splsoftcam();
272 periph_name = p_drv->driver_name;
273 for (;;newunit++) {
274
275 for (periph = TAILQ_FIRST(&p_drv->units);
276 periph != NULL && periph->unit_number != newunit;
277 periph = TAILQ_NEXT(periph, unit_links))
278 ;
279
280 if (periph != NULL && periph->unit_number == newunit) {
281 if (wired != 0) {
282 xpt_print_path(periph->path);
283 printf("Duplicate Wired Device entry!\n");
284 xpt_print_path(periph->path);
285 printf("Second device will not be wired\n");
286 wired = 0;
287 }
288 continue;
289 }
290
291 for (periph_conf = cam_pinit;
292 wired == 0 && periph_conf->periph_name != NULL;
293 periph_conf++) {
294
295 /*
296 * Don't match entries like "da 4" as a wired down
297 * device, but do match entries like "da 4 target 5"
298 * or even "da 4 scbus 1".
299 */
300 if (IS_SPECIFIED(periph_conf->periph_unit)
301 && (!strcmp(periph_name, periph_conf->periph_name))
302 && (IS_SPECIFIED(periph_conf->target)
303 || IS_SPECIFIED(periph_conf->pathid))
304 && (newunit == periph_conf->periph_unit))
305 break;
306 }
307
308 if (wired != 0 || periph_conf->periph_name == NULL)
309 break;
310 }
311 splx(s);
312 return (newunit);
313}
314
315static u_int
316camperiphunit(struct periph_driver *p_drv, path_id_t pathid,
317 target_id_t target, lun_id_t lun)
318{
319 struct cam_periph_config *periph_conf;
320 u_int unit;
321 int hit;
322
323 unit = 0;
324 hit = 0;
325
326 for (periph_conf = cam_pinit;
327 periph_conf->periph_name != NULL;
328 periph_conf++, hit = 0) {
329
330 if (!strcmp(p_drv->driver_name, periph_conf->periph_name)
331 && IS_SPECIFIED(periph_conf->periph_unit)) {
332
333 if (IS_SPECIFIED(periph_conf->pathid)) {
334
335 if (pathid != periph_conf->pathid)
336 continue;
337 hit++;
338 }
339
340 if (IS_SPECIFIED(periph_conf->target)) {
341
342 if (target != periph_conf->target)
343 continue;
344 hit++;
345 }
346
347 if (IS_SPECIFIED(periph_conf->lun)) {
348
349 if (lun != periph_conf->lun)
350 continue;
351 hit++;
352 }
353
354 if (hit != 0) {
355 unit = periph_conf->periph_unit;
356 break;
357 }
358 }
359 }
360
361 /*
362 * Either start from 0 looking for the next unit or from
363 * the unit number given in the periph_conf. This way,
364 * if we have wildcard matches, we don't return the same
365 * unit number twice.
366 */
367 unit = camperiphnextunit(p_drv, unit, /*wired*/hit);
368
369 return (unit);
370}
371
372void
373cam_periph_invalidate(struct cam_periph *periph)
374{
375 int s;
376
377 s = splsoftcam();
378 /*
379 * We only call this routine the first time a peripheral is
380 * invalidated. The oninvalidate() routine is always called at
381 * splsoftcam().
382 */
383 if (((periph->flags & CAM_PERIPH_INVALID) == 0)
384 && (periph->periph_oninval != NULL))
385 periph->periph_oninval(periph);
386
387 periph->flags |= CAM_PERIPH_INVALID;
388 periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND;
389
390 if (periph->refcount == 0)
391 camperiphfree(periph);
392 else if (periph->refcount < 0)
393 printf("cam_invalidate_periph: refcount < 0!!\n");
394 splx(s);
395}
396
397static void
398camperiphfree(struct cam_periph *periph)
399{
400 int s;
401 struct periph_driver **p_drv;
402
403 for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
404 *p_drv != NULL; p_drv++) {
405 if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0)
406 break;
407 }
408
409 if (periph->periph_dtor != NULL)
410 periph->periph_dtor(periph);
411
412 s = splsoftcam();
413 TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links);
414 (*p_drv)->generation++;
415 splx(s);
416
417 xpt_remove_periph(periph);
418
419 if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) {
420 union ccb ccb;
421 void *arg;
422
423 switch (periph->deferred_ac) {
424 case AC_FOUND_DEVICE:
425 ccb.ccb_h.func_code = XPT_GDEV_TYPE;
426 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
427 xpt_action(&ccb);
428 arg = &ccb;
429 break;
430 case AC_PATH_REGISTERED:
431 ccb.ccb_h.func_code = XPT_PATH_INQ;
432 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/ 1);
433 xpt_action(&ccb);
434 arg = &ccb;
435 break;
436 default:
437 arg = NULL;
438 break;
439 }
440 periph->deferred_callback(NULL, periph->deferred_ac,
441 periph->path, arg);
442 }
443 xpt_free_path(periph->path);
444 free(periph, M_DEVBUF);
445}
446
447/*
448 * Wait interruptibly for an exclusive lock.
449 */
450int
451cam_periph_lock(struct cam_periph *periph, int priority)
452{
453 int error;
454
455 while ((periph->flags & CAM_PERIPH_LOCKED) != 0) {
456 periph->flags |= CAM_PERIPH_LOCK_WANTED;
457 if ((error = tsleep(periph, priority, "caplck", 0)) != 0)
458 return error;
459 }
460
461 if (cam_periph_acquire(periph) != CAM_REQ_CMP)
462 return(ENXIO);
463
464 periph->flags |= CAM_PERIPH_LOCKED;
465 return 0;
466}
467
468/*
469 * Unlock and wake up any waiters.
470 */
471void
472cam_periph_unlock(struct cam_periph *periph)
473{
474 periph->flags &= ~CAM_PERIPH_LOCKED;
475 if ((periph->flags & CAM_PERIPH_LOCK_WANTED) != 0) {
476 periph->flags &= ~CAM_PERIPH_LOCK_WANTED;
477 wakeup(periph);
478 }
479
480 cam_periph_release(periph);
481}
482
483/*
484 * Map user virtual pointers into kernel virtual address space, so we can
485 * access the memory. This won't work on physical pointers, for now it's
486 * up to the caller to check for that. (XXX KDM -- should we do that here
487 * instead?) This also only works for up to MAXPHYS memory. Since we use
488 * buffers to map stuff in and out, we're limited to the buffer size.
489 */
490int
491cam_periph_mapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
492{
493 int flags, numbufs, i;
493 int numbufs, i;
494 int flags[CAM_PERIPH_MAXMAPS];
494 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
495 u_int32_t lengths[CAM_PERIPH_MAXMAPS];
496 u_int32_t dirs[CAM_PERIPH_MAXMAPS];
497
498 switch(ccb->ccb_h.func_code) {
499 case XPT_DEV_MATCH:
495 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
496 u_int32_t lengths[CAM_PERIPH_MAXMAPS];
497 u_int32_t dirs[CAM_PERIPH_MAXMAPS];
498
499 switch(ccb->ccb_h.func_code) {
500 case XPT_DEV_MATCH:
500 if (ccb->cdm.pattern_buf_len > MAXPHYS) {
501 printf("cam_periph_mapmem: attempt to map %u bytes, "
502 "which is greater than MAXPHYS(%d)\n",
503 ccb->cdm.pattern_buf_len, MAXPHYS);
504 return(E2BIG);
505 } else if (ccb->cdm.match_buf_len > MAXPHYS) {
506 printf("cam_periph_mapmem: attempt to map %u bytes, "
507 "which is greater than MAXPHYS(%d)\n",
508 ccb->cdm.match_buf_len, MAXPHYS);
509 return(E2BIG);
510 }
511 if (ccb->cdm.match_buf_len == 0) {
512 printf("cam_periph_mapmem: invalid match buffer "
513 "length 0\n");
514 return(EINVAL);
515 }
516 if (ccb->cdm.pattern_buf_len > 0) {
517 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
518 lengths[0] = ccb->cdm.pattern_buf_len;
519 dirs[0] = CAM_DIR_OUT;
520 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
521 lengths[1] = ccb->cdm.match_buf_len;
522 dirs[1] = CAM_DIR_IN;
523 numbufs = 2;
524 } else {
525 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
526 lengths[0] = ccb->cdm.match_buf_len;
527 dirs[0] = CAM_DIR_IN;
528 numbufs = 1;
529 }
530 break;
531 case XPT_SCSI_IO:
501 if (ccb->cdm.match_buf_len == 0) {
502 printf("cam_periph_mapmem: invalid match buffer "
503 "length 0\n");
504 return(EINVAL);
505 }
506 if (ccb->cdm.pattern_buf_len > 0) {
507 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
508 lengths[0] = ccb->cdm.pattern_buf_len;
509 dirs[0] = CAM_DIR_OUT;
510 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
511 lengths[1] = ccb->cdm.match_buf_len;
512 dirs[1] = CAM_DIR_IN;
513 numbufs = 2;
514 } else {
515 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
516 lengths[0] = ccb->cdm.match_buf_len;
517 dirs[0] = CAM_DIR_IN;
518 numbufs = 1;
519 }
520 break;
521 case XPT_SCSI_IO:
532 if (ccb->csio.dxfer_len > MAXPHYS) {
533 printf("cam_periph_mapmem: attempt to map %u bytes, "
534 "which is greater than MAXPHYS(%d)\n",
535 ccb->csio.dxfer_len, MAXPHYS);
536 return(E2BIG);
537 }
538
539 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
540 return(0);
541
542 data_ptrs[0] = &ccb->csio.data_ptr;
522 if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE)
523 return(0);
524
525 data_ptrs[0] = &ccb->csio.data_ptr;
543 lengths[0] = ccb->csio.dxfer_len;;
526 lengths[0] = ccb->csio.dxfer_len;
544 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
545 numbufs = 1;
546 break;
547 default:
548 return(EINVAL);
549 break; /* NOTREACHED */
550 }
551
527 dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK;
528 numbufs = 1;
529 break;
530 default:
531 return(EINVAL);
532 break; /* NOTREACHED */
533 }
534
552 /* this keeps the current process from getting swapped */
553 /*
535 /*
554 * XXX KDM should I use P_NOSWAP instead?
536 * Check the transfer length and permissions first, so we don't
537 * have to unmap any previously mapped buffers.
555 */
538 */
556 curproc->p_flag |= P_PHYSIO;
557
558 for (i = 0; i < numbufs; i++) {
539 for (i = 0; i < numbufs; i++) {
559 flags = 0;
560
540
541 flags[i] = 0;
542
543 /*
544 * The userland data pointer passed in may not be page
545 * aligned. vmapbuf() truncates the address to a page
546 * boundary, so if the address isn't page aligned, we'll
547 * need enough space for the given transfer length, plus
548 * whatever extra space is necessary to make it to the page
549 * boundary.
550 */
551 if ((lengths[i] +
552 (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK)) > MAXPHYS){
553 printf("cam_periph_mapmem: attempt to map %u bytes, "
554 "which is greater than MAXPHYS(%d)\n",
555 lengths[i] +
556 (((vm_offset_t)(*data_ptrs[i])) & PAGE_MASK),
557 MAXPHYS);
558 return(E2BIG);
559 }
560
561 if (dirs[i] & CAM_DIR_IN) {
561 if (dirs[i] & CAM_DIR_IN) {
562 flags = B_READ;
562 flags[i] = B_READ;
563 if (useracc(*data_ptrs[i], lengths[i], B_READ) == 0){
564 printf("cam_periph_mapmem: error, "
565 "address %p, length %lu isn't "
566 "user accessible for READ\n",
567 (void *)*data_ptrs[i],
568 (u_long)lengths[i]);
563 if (useracc(*data_ptrs[i], lengths[i], B_READ) == 0){
564 printf("cam_periph_mapmem: error, "
565 "address %p, length %lu isn't "
566 "user accessible for READ\n",
567 (void *)*data_ptrs[i],
568 (u_long)lengths[i]);
569 /*
570 * If we've already mapped one or more
571 * buffers for this CCB, unmap it (them).
572 */
573 if (i > 0)
574 cam_periph_unmapmem(ccb, mapinfo);
575 else
576 curproc->p_flag &= ~P_PHYSIO;
577
578 return(EACCES);
579 }
580 }
581
582 /*
583 * XXX this check is really bogus, since B_WRITE currently
584 * is all 0's, and so it is "set" all the time.
585 */
586 if (dirs[i] & CAM_DIR_OUT) {
569 return(EACCES);
570 }
571 }
572
573 /*
574 * XXX this check is really bogus, since B_WRITE currently
575 * is all 0's, and so it is "set" all the time.
576 */
577 if (dirs[i] & CAM_DIR_OUT) {
587 flags |= B_WRITE;
578 flags[i] |= B_WRITE;
588 if (useracc(*data_ptrs[i], lengths[i], B_WRITE) == 0){
589 printf("cam_periph_mapmem: error, "
590 "address %p, length %lu isn't "
591 "user accessible for WRITE\n",
592 (void *)*data_ptrs[i],
593 (u_long)lengths[i]);
579 if (useracc(*data_ptrs[i], lengths[i], B_WRITE) == 0){
580 printf("cam_periph_mapmem: error, "
581 "address %p, length %lu isn't "
582 "user accessible for WRITE\n",
583 (void *)*data_ptrs[i],
584 (u_long)lengths[i]);
594 /*
595 * If we've already mapped one or more
596 * buffers for this CCB, unmap it (them).
597 */
598 if (i > 0)
599 cam_periph_unmapmem(ccb, mapinfo);
600 else
601 curproc->p_flag &= ~P_PHYSIO;
602
603 return(EACCES);
604 }
605 }
606
585
586 return(EACCES);
587 }
588 }
589
590 }
591
592 /* this keeps the current process from getting swapped */
593 /*
594 * XXX KDM should I use P_NOSWAP instead?
595 */
596 curproc->p_flag |= P_PHYSIO;
597
598 for (i = 0; i < numbufs; i++) {
607 /*
608 * Get the buffer.
609 */
610 mapinfo->bp[i] = getpbuf();
611
612 /* save the buffer's data address */
613 mapinfo->bp[i]->b_saveaddr = mapinfo->bp[i]->b_data;
614
615 /* put our pointer in the data slot */
616 mapinfo->bp[i]->b_data = *data_ptrs[i];
617
599 /*
600 * Get the buffer.
601 */
602 mapinfo->bp[i] = getpbuf();
603
604 /* save the buffer's data address */
605 mapinfo->bp[i]->b_saveaddr = mapinfo->bp[i]->b_data;
606
607 /* put our pointer in the data slot */
608 mapinfo->bp[i]->b_data = *data_ptrs[i];
609
618 /* set the transfer length, we know it's < 64K */
610 /* set the transfer length, we know it's < MAXPHYS */
619 mapinfo->bp[i]->b_bufsize = lengths[i];
620
621 /* set the flags */
611 mapinfo->bp[i]->b_bufsize = lengths[i];
612
613 /* set the flags */
622 mapinfo->bp[i]->b_flags = flags | B_PHYS | B_BUSY;
614 mapinfo->bp[i]->b_flags = flags[i] | B_PHYS | B_BUSY;
623
624 /* map the buffer into kernel memory */
625 vmapbuf(mapinfo->bp[i]);
626
627 /* set our pointer to the new mapped area */
628 *data_ptrs[i] = mapinfo->bp[i]->b_data;
629
630 mapinfo->num_bufs_used++;
631 }
632
633 return(0);
634}
635
636/*
637 * Unmap memory segments mapped into kernel virtual address space by
638 * cam_periph_mapmem().
639 */
640void
641cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
642{
643 int numbufs, i;
644 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
645
646 if (mapinfo->num_bufs_used <= 0) {
647 /* allow ourselves to be swapped once again */
648 curproc->p_flag &= ~P_PHYSIO;
649 return;
650 }
651
652 switch (ccb->ccb_h.func_code) {
653 case XPT_DEV_MATCH:
654 numbufs = min(mapinfo->num_bufs_used, 2);
655
656 if (numbufs == 1) {
657 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
658 } else {
659 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
660 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
661 }
662 break;
663 case XPT_SCSI_IO:
664 data_ptrs[0] = &ccb->csio.data_ptr;
665 numbufs = min(mapinfo->num_bufs_used, 1);
666 break;
667 default:
668 /* allow ourselves to be swapped once again */
669 curproc->p_flag &= ~P_PHYSIO;
670 return;
671 break; /* NOTREACHED */
672 }
673
674 for (i = 0; i < numbufs; i++) {
675 /* Set the user's pointer back to the original value */
676 *data_ptrs[i] = mapinfo->bp[i]->b_saveaddr;
677
678 /* unmap the buffer */
679 vunmapbuf(mapinfo->bp[i]);
680
681 /* clear the flags we set above */
682 mapinfo->bp[i]->b_flags &= ~(B_PHYS|B_BUSY);
683
684 /* release the buffer */
685 relpbuf(mapinfo->bp[i]);
686 }
687
688 /* allow ourselves to be swapped once again */
689 curproc->p_flag &= ~P_PHYSIO;
690}
691
692union ccb *
693cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
694{
695 struct ccb_hdr *ccb_h;
696 int s;
697
698 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetccb\n"));
699
700 s = splsoftcam();
701
702 while (periph->ccb_list.slh_first == NULL) {
703 if (periph->immediate_priority > priority)
704 periph->immediate_priority = priority;
705 xpt_schedule(periph, priority);
706 if ((periph->ccb_list.slh_first != NULL)
707 && (periph->ccb_list.slh_first->pinfo.priority == priority))
708 break;
709 tsleep(&periph->ccb_list, PRIBIO, "cgticb", 0);
710 }
711
712 ccb_h = periph->ccb_list.slh_first;
713 SLIST_REMOVE_HEAD(&periph->ccb_list, periph_links.sle);
714 splx(s);
715 return ((union ccb *)ccb_h);
716}
717
718void
719cam_periph_ccbwait(union ccb *ccb)
720{
721 int s;
722
723 s = splsoftcam();
724 if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
725 || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
726 tsleep(&ccb->ccb_h.cbfcnp, PRIBIO, "cbwait", 0);
727
728 splx(s);
729}
730
731int
732cam_periph_ioctl(struct cam_periph *periph, int cmd, caddr_t addr,
733 int (*error_routine)(union ccb *ccb,
734 cam_flags camflags,
735 u_int32_t sense_flags))
736{
737 union ccb *ccb;
738 int error;
739 int found;
740
741 error = found = 0;
742
743 switch(cmd){
744 case CAMGETPASSTHRU:
745 ccb = cam_periph_getccb(periph, /* priority */ 1);
746 xpt_setup_ccb(&ccb->ccb_h,
747 ccb->ccb_h.path,
748 /*priority*/1);
749 ccb->ccb_h.func_code = XPT_GDEVLIST;
750
751 /*
752 * Basically, the point of this is that we go through
753 * getting the list of devices, until we find a passthrough
754 * device. In the current version of the CAM code, the
755 * only way to determine what type of device we're dealing
756 * with is by its name.
757 */
758 while (found == 0) {
759 ccb->cgdl.index = 0;
760 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
761 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
762
763 /* we want the next device in the list */
764 xpt_action(ccb);
765 if (strncmp(ccb->cgdl.periph_name,
766 "pass", 4) == 0){
767 found = 1;
768 break;
769 }
770 }
771 if ((ccb->cgdl.status == CAM_GDEVLIST_LAST_DEVICE) &&
772 (found == 0)) {
773 ccb->cgdl.periph_name[0] = '\0';
774 ccb->cgdl.unit_number = 0;
775 break;
776 }
777 }
778
779 /* copy the result back out */
780 bcopy(ccb, addr, sizeof(union ccb));
781
782 /* and release the ccb */
783 xpt_release_ccb(ccb);
784
785 break;
786 default:
787 error = ENOTTY;
788 break;
789 }
790 return(error);
791}
792
793int
794cam_periph_runccb(union ccb *ccb,
795 int (*error_routine)(union ccb *ccb,
796 cam_flags camflags,
797 u_int32_t sense_flags),
798 cam_flags camflags, u_int32_t sense_flags,
799 struct devstat *ds)
800{
801 int error;
802
803 error = 0;
804
805 /*
806 * If the user has supplied a stats structure, and if we understand
807 * this particular type of ccb, record the transaction start.
808 */
809 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
810 devstat_start_transaction(ds);
811
812 xpt_action(ccb);
813
814 do {
815 cam_periph_ccbwait(ccb);
816 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
817 error = 0;
818 else if (error_routine != NULL)
819 error = (*error_routine)(ccb, camflags, sense_flags);
820 else
821 error = 0;
822
823 } while (error == ERESTART);
824
825 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
826 cam_release_devq(ccb->ccb_h.path,
827 /* relsim_flags */0,
828 /* openings */0,
829 /* timeout */0,
830 /* getcount_only */ FALSE);
831
832 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
833 devstat_end_transaction(ds,
834 ccb->csio.dxfer_len,
835 ccb->csio.tag_action & 0xf,
836 ((ccb->ccb_h.flags & CAM_DIR_MASK) ==
837 CAM_DIR_NONE) ? DEVSTAT_NO_DATA :
838 (ccb->ccb_h.flags & CAM_DIR_OUT) ?
839 DEVSTAT_WRITE :
840 DEVSTAT_READ);
841
842 return(error);
843}
844
845u_int32_t
846cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
847 u_int32_t openings, u_int32_t timeout,
848 int getcount_only)
849{
850 struct ccb_relsim crs;
851
852 xpt_setup_ccb(&crs.ccb_h, path,
853 /*priority*/1);
854 crs.ccb_h.func_code = XPT_REL_SIMQ;
855 crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0;
856 crs.release_flags = relsim_flags;
857 crs.openings = openings;
858 crs.release_timeout = timeout;
859 xpt_action((union ccb *)&crs);
860 return (crs.qfrozen_cnt);
861}
862
863#define saved_ccb_ptr ppriv_ptr0
864static void
865camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
866{
867 cam_status status;
868 int frozen;
869 int sense;
870 struct scsi_start_stop_unit *scsi_cmd;
871 u_int32_t relsim_flags, timeout;
872 u_int32_t qfrozen_cnt;
873
874 status = done_ccb->ccb_h.status;
875 frozen = (status & CAM_DEV_QFRZN) != 0;
876 sense = (status & CAM_AUTOSNS_VALID) != 0;
877 status &= CAM_STATUS_MASK;
878
879 timeout = 0;
880 relsim_flags = 0;
881
882 /*
883 * Unfreeze the queue once if it is already frozen..
884 */
885 if (frozen != 0) {
886 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
887 /*relsim_flags*/0,
888 /*openings*/0,
889 /*timeout*/0,
890 /*getcount_only*/0);
891 }
892
893 switch (status) {
894
895 case CAM_REQ_CMP:
896
897 /*
898 * If we have successfully taken a device from the not
899 * ready to ready state, re-scan the device and re-get the
900 * inquiry information. Many devices (mostly disks) don't
901 * properly report their inquiry information unless they
902 * are spun up.
903 */
904 if (done_ccb->ccb_h.func_code == XPT_SCSI_IO) {
905 scsi_cmd = (struct scsi_start_stop_unit *)
906 &done_ccb->csio.cdb_io.cdb_bytes;
907
908 if (scsi_cmd->opcode == START_STOP_UNIT)
909 xpt_async(AC_INQ_CHANGED,
910 done_ccb->ccb_h.path, NULL);
911 }
912 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
913 sizeof(union ccb));
914
915 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
916
917 xpt_action(done_ccb);
918
919 break;
920 case CAM_SCSI_STATUS_ERROR:
921 scsi_cmd = (struct scsi_start_stop_unit *)
922 &done_ccb->csio.cdb_io.cdb_bytes;
923 if (sense != 0) {
924 struct scsi_sense_data *sense;
925 int error_code, sense_key, asc, ascq;
926
927 sense = &done_ccb->csio.sense_data;
928 scsi_extract_sense(sense, &error_code,
929 &sense_key, &asc, &ascq);
930
931 /*
932 * If the error is "invalid field in CDB",
933 * and the load/eject flag is set, turn the
934 * flag off and try again. This is just in
935 * case the drive in question barfs on the
936 * load eject flag. The CAM code should set
937 * the load/eject flag by default for
938 * removable media.
939 */
940
941 /* XXX KDM
942 * Should we check to see what the specific
943 * scsi status is?? Or does it not matter
944 * since we already know that there was an
945 * error, and we know what the specific
946 * error code was, and we know what the
947 * opcode is..
948 */
949 if ((scsi_cmd->opcode == START_STOP_UNIT) &&
950 ((scsi_cmd->how & SSS_LOEJ) != 0) &&
951 (asc == 0x24) && (ascq == 0x00) &&
952 (done_ccb->ccb_h.retry_count > 0)) {
953
954 scsi_cmd->how &= ~SSS_LOEJ;
955
956 xpt_action(done_ccb);
957
958 } else if (done_ccb->ccb_h.retry_count > 0) {
959 /*
960 * In this case, the error recovery
961 * command failed, but we've got
962 * some retries left on it. Give
963 * it another try.
964 */
965
966 /* set the timeout to .5 sec */
967 relsim_flags =
968 RELSIM_RELEASE_AFTER_TIMEOUT;
969 timeout = 500;
970
971 xpt_action(done_ccb);
972
973 break;
974
975 } else {
976 /*
977 * Copy the original CCB back and
978 * send it back to the caller.
979 */
980 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
981 done_ccb, sizeof(union ccb));
982
983 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
984
985 xpt_action(done_ccb);
986 }
987 } else {
988 /*
989 * Eh?? The command failed, but we don't
990 * have any sense. What's up with that?
991 * Fire the CCB again to return it to the
992 * caller.
993 */
994 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
995 done_ccb, sizeof(union ccb));
996
997 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
998
999 xpt_action(done_ccb);
1000
1001 }
1002 break;
1003 default:
1004 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
1005 sizeof(union ccb));
1006
1007 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1008
1009 xpt_action(done_ccb);
1010
1011 break;
1012 }
1013
1014 /* decrement the retry count */
1015 if (done_ccb->ccb_h.retry_count > 0)
1016 done_ccb->ccb_h.retry_count--;
1017
1018 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
1019 /*relsim_flags*/relsim_flags,
1020 /*openings*/0,
1021 /*timeout*/timeout,
1022 /*getcount_only*/0);
1023}
1024
1025/*
1026 * Generic error handler. Peripheral drivers usually filter
1027 * out the errors that they handle in a unique mannor, then
1028 * call this function.
1029 */
1030int
1031cam_periph_error(union ccb *ccb, cam_flags camflags,
1032 u_int32_t sense_flags, union ccb *save_ccb)
1033{
1034 cam_status status;
1035 int frozen;
1036 int sense;
1037 int error;
1038 int openings;
1039 int retry;
1040 u_int32_t relsim_flags;
1041 u_int32_t timeout;
1042
1043 status = ccb->ccb_h.status;
1044 frozen = (status & CAM_DEV_QFRZN) != 0;
1045 sense = (status & CAM_AUTOSNS_VALID) != 0;
1046 status &= CAM_STATUS_MASK;
1047 relsim_flags = 0;
1048
1049
1050 switch (status) {
1051 case CAM_REQ_CMP:
1052 /* decrement the number of retries */
1053 retry = ccb->ccb_h.retry_count > 0;
1054 if (retry)
1055 ccb->ccb_h.retry_count--;
1056 error = 0;
1057 break;
1058 case CAM_SCSI_STATUS_ERROR:
1059
1060 switch (ccb->csio.scsi_status) {
1061 case SCSI_STATUS_OK:
1062 case SCSI_STATUS_COND_MET:
1063 case SCSI_STATUS_INTERMED:
1064 case SCSI_STATUS_INTERMED_COND_MET:
1065 error = 0;
1066 break;
1067 case SCSI_STATUS_CMD_TERMINATED:
1068 case SCSI_STATUS_CHECK_COND:
1069 if (sense != 0) {
1070 struct scsi_sense_data *sense;
1071 int error_code, sense_key, asc, ascq;
1072 struct cam_periph *periph;
1073 scsi_sense_action err_action;
1074 struct ccb_getdev cgd;
1075
1076 sense = &ccb->csio.sense_data;
1077 scsi_extract_sense(sense, &error_code,
1078 &sense_key, &asc, &ascq);
1079 periph = xpt_path_periph(ccb->ccb_h.path);
1080
1081 /*
1082 * Grab the inquiry data for this device.
1083 */
1084 xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path,
1085 /*priority*/ 1);
1086 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1087 xpt_action((union ccb *)&cgd);
1088
1089 err_action = scsi_error_action(asc, ascq,
1090 &cgd.inq_data);
1091
1092 /*
1093 * Send a Test Unit Ready to the device.
1094 * If the 'many' flag is set, we send 120
1095 * test unit ready commands, one every half
1096 * second. Otherwise, we just send one TUR.
1097 * We only want to do this if the retry
1098 * count has not been exhausted.
1099 */
1100 if (((err_action & SS_MASK) == SS_TUR)
1101 && save_ccb != NULL
1102 && ccb->ccb_h.retry_count > 0) {
1103
1104 /*
1105 * Since error recovery is already
1106 * in progress, don't attempt to
1107 * process this error. It is probably
1108 * related to the error that caused
1109 * the currently active error recovery
1110 * action. Also, we only have
1111 * space for one saved CCB, so if we
1112 * had two concurrent error recovery
1113 * actions, we would end up
1114 * over-writing one error recovery
1115 * CCB with another one.
1116 */
1117 if (periph->flags &
1118 CAM_PERIPH_RECOVERY_INPROG) {
1119 error = ERESTART;
1120 break;
1121 }
1122
1123 periph->flags |=
1124 CAM_PERIPH_RECOVERY_INPROG;
1125
1126 /* decrement the number of retries */
1127 if ((err_action &
1128 SSQ_DECREMENT_COUNT) != 0) {
1129 retry = 1;
1130 ccb->ccb_h.retry_count--;
1131 }
1132
1133 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1134
1135 /*
1136 * We retry this one every half
1137 * second for a minute. If the
1138 * device hasn't become ready in a
1139 * minute's time, it's unlikely to
1140 * ever become ready. If the table
1141 * doesn't specify SSQ_MANY, we can
1142 * only try this once. Oh well.
1143 */
1144 if ((err_action & SSQ_MANY) != 0)
1145 scsi_test_unit_ready(&ccb->csio,
1146 /*retries*/120,
1147 camperiphdone,
1148 MSG_SIMPLE_Q_TAG,
1149 SSD_FULL_SIZE,
1150 /*timeout*/5000);
1151 else
1152 scsi_test_unit_ready(&ccb->csio,
1153 /*retries*/1,
1154 camperiphdone,
1155 MSG_SIMPLE_Q_TAG,
1156 SSD_FULL_SIZE,
1157 /*timeout*/5000);
1158
1159 /* release the queue after .5 sec. */
1160 relsim_flags =
1161 RELSIM_RELEASE_AFTER_TIMEOUT;
1162 timeout = 500;
1163 /*
1164 * Drop the priority to 0 so that
1165 * we are the first to execute. Also
1166 * freeze the queue after this command
1167 * is sent so that we can restore the
1168 * old csio and have it queued in the
1169 * proper order before we let normal
1170 * transactions go to the drive.
1171 */
1172 ccb->ccb_h.pinfo.priority = 0;
1173 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1174
1175 /*
1176 * Save a pointer to the original
1177 * CCB in the new CCB.
1178 */
1179 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1180
1181 error = ERESTART;
1182 }
1183 /*
1184 * Send a start unit command to the device,
1185 * and then retry the command. We only
1186 * want to do this if the retry count has
1187 * not been exhausted. If the user
1188 * specified 0 retries, then we follow
1189 * their request and do not retry.
1190 */
1191 else if (((err_action & SS_MASK) == SS_START)
1192 && save_ccb != NULL
1193 && ccb->ccb_h.retry_count > 0) {
1194 int le;
1195
1196 /*
1197 * Only one error recovery action
1198 * at a time. See above.
1199 */
1200 if (periph->flags &
1201 CAM_PERIPH_RECOVERY_INPROG) {
1202 error = ERESTART;
1203 break;
1204 }
1205
1206 periph->flags |=
1207 CAM_PERIPH_RECOVERY_INPROG;
1208
1209 /* decrement the number of retries */
1210 retry = 1;
1211 ccb->ccb_h.retry_count--;
1212
1213 /*
1214 * Check for removable media and
1215 * set load/eject flag
1216 * appropriately.
1217 */
1218 if (SID_IS_REMOVABLE(&cgd.inq_data))
1219 le = TRUE;
1220 else
1221 le = FALSE;
1222
1223 /*
1224 * Attempt to start the drive up.
1225 *
1226 * Save the current ccb so it can
1227 * be restored and retried once the
1228 * drive is started up.
1229 */
1230 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1231
1232 scsi_start_stop(&ccb->csio,
1233 /*retries*/1,
1234 camperiphdone,
1235 MSG_SIMPLE_Q_TAG,
1236 /*start*/TRUE,
1237 /*load/eject*/le,
1238 /*immediate*/FALSE,
1239 SSD_FULL_SIZE,
1240 /*timeout*/50000);
1241 /*
1242 * Drop the priority to 0 so that
1243 * we are the first to execute. Also
1244 * freeze the queue after this command
1245 * is sent so that we can restore the
1246 * old csio and have it queued in the
1247 * proper order before we let normal
1248 * transactions go to the drive.
1249 */
1250 ccb->ccb_h.pinfo.priority = 0;
1251 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1252
1253 /*
1254 * Save a pointer to the original
1255 * CCB in the new CCB.
1256 */
1257 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1258
1259 error = ERESTART;
1260 } else if ((sense_flags & SF_RETRY_UA) != 0) {
1261 /*
1262 * XXX KDM this is a *horrible*
1263 * hack.
1264 */
1265 error = scsi_interpret_sense(ccb,
1266 sense_flags,
1267 &relsim_flags,
1268 &openings,
1269 &timeout,
1270 err_action);
1271 }
1272
1273 /*
1274 * Theoretically, this code should send a
1275 * test unit ready to the given device, and
1276 * if it returns and error, send a start
1277 * unit command. Since we don't yet have
1278 * the capability to do two-command error
1279 * recovery, just send a start unit.
1280 * XXX KDM fix this!
1281 */
1282 else if (((err_action & SS_MASK) == SS_TURSTART)
1283 && save_ccb != NULL
1284 && ccb->ccb_h.retry_count > 0) {
1285 int le;
1286
1287 /*
1288 * Only one error recovery action
1289 * at a time. See above.
1290 */
1291 if (periph->flags &
1292 CAM_PERIPH_RECOVERY_INPROG) {
1293 error = ERESTART;
1294 break;
1295 }
1296
1297 periph->flags |=
1298 CAM_PERIPH_RECOVERY_INPROG;
1299
1300 /* decrement the number of retries */
1301 retry = 1;
1302 ccb->ccb_h.retry_count--;
1303
1304 /*
1305 * Check for removable media and
1306 * set load/eject flag
1307 * appropriately.
1308 */
1309 if (SID_IS_REMOVABLE(&cgd.inq_data))
1310 le = TRUE;
1311 else
1312 le = FALSE;
1313
1314 /*
1315 * Attempt to start the drive up.
1316 *
1317 * Save the current ccb so it can
1318 * be restored and retried once the
1319 * drive is started up.
1320 */
1321 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1322
1323 scsi_start_stop(&ccb->csio,
1324 /*retries*/1,
1325 camperiphdone,
1326 MSG_SIMPLE_Q_TAG,
1327 /*start*/TRUE,
1328 /*load/eject*/le,
1329 /*immediate*/FALSE,
1330 SSD_FULL_SIZE,
1331 /*timeout*/50000);
1332
1333 /* release the queue after .5 sec. */
1334 relsim_flags =
1335 RELSIM_RELEASE_AFTER_TIMEOUT;
1336 timeout = 500;
1337 /*
1338 * Drop the priority to 0 so that
1339 * we are the first to execute. Also
1340 * freeze the queue after this command
1341 * is sent so that we can restore the
1342 * old csio and have it queued in the
1343 * proper order before we let normal
1344 * transactions go to the drive.
1345 */
1346 ccb->ccb_h.pinfo.priority = 0;
1347 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1348
1349 /*
1350 * Save a pointer to the original
1351 * CCB in the new CCB.
1352 */
1353 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1354
1355 error = ERESTART;
1356 } else {
1357 error = scsi_interpret_sense(ccb,
1358 sense_flags,
1359 &relsim_flags,
1360 &openings,
1361 &timeout,
1362 err_action);
1363 }
1364 } else if (ccb->csio.scsi_status ==
1365 SCSI_STATUS_CHECK_COND) {
1366 /* no point in decrementing the retry count */
1367 panic("cam_periph_error: scsi status of "
1368 "CHECK COND returned but no sense "
1369 "information is availible. "
1370 "Controller should have returned "
1371 "CAM_AUTOSENSE_FAILED");
1372 /* NOTREACHED */
1373 error = EIO;
1374 } else if (ccb->ccb_h.retry_count > 0) {
1375 /*
1376 * XXX KDM shouldn't there be a better
1377 * argument to return??
1378 */
1379 error = EIO;
1380 } else {
1381 /* decrement the number of retries */
1382 retry = ccb->ccb_h.retry_count > 0;
1383 if (retry)
1384 ccb->ccb_h.retry_count--;
1385 /*
1386 * If it was aborted with no
1387 * clue as to the reason, just
1388 * retry it again.
1389 */
1390 error = ERESTART;
1391 }
1392 break;
1393 case SCSI_STATUS_QUEUE_FULL:
1394 {
1395 /* no decrement */
1396 struct ccb_getdev cgd;
1397
1398 /*
1399 * First off, find out what the current
1400 * transaction counts are.
1401 */
1402 xpt_setup_ccb(&cgd.ccb_h,
1403 ccb->ccb_h.path,
1404 /*priority*/1);
1405 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1406 xpt_action((union ccb *)&cgd);
1407
1408 /*
1409 * If we were the only transaction active, treat
1410 * the QUEUE FULL as if it were a BUSY condition.
1411 */
1412 if (cgd.dev_active != 0) {
1413 /*
1414 * Reduce the number of openings to
1415 * be 1 less than the amount it took
1416 * to get a queue full bounded by the
1417 * minimum allowed tag count for this
1418 * device.
1419 */
1420 openings = cgd.dev_active;
1421 if (openings < cgd.mintags)
1422 openings = cgd.mintags;
1423 if (openings < cgd.dev_active+cgd.dev_openings)
1424 relsim_flags = RELSIM_ADJUST_OPENINGS;
1425 else {
1426 /*
1427 * Some devices report queue full for
1428 * temporary resource shortages. For
1429 * this reason, we allow a minimum
1430 * tag count to be entered via a
1431 * quirk entry to prevent the queue
1432 * count on these devices from falling
1433 * to a pessimisticly low value. We
1434 * still wait for the next successful
1435 * completion, however, before queueing
1436 * more transactions to the device.
1437 */
1438 relsim_flags =
1439 RELSIM_RELEASE_AFTER_CMDCMPLT;
1440 }
1441 timeout = 0;
1442 error = ERESTART;
1443 break;
1444 }
1445 /* FALLTHROUGH */
1446 }
1447 case SCSI_STATUS_BUSY:
1448 /*
1449 * Restart the queue after either another
1450 * command completes or a 1 second timeout.
1451 */
1452 /*
1453 * XXX KDM ask JTG about this again, do we need to
1454 * be looking at the retry count here?
1455 */
1456 error = ERESTART;
1457 relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT
1458 | RELSIM_RELEASE_AFTER_CMDCMPLT;
1459 timeout = 1000;
1460 break;
1461 case SCSI_STATUS_RESERV_CONFLICT:
1462 error = EIO;
1463 break;
1464 default:
1465 error = EIO;
1466 break;
1467 }
1468 break;
1469 case CAM_REQ_CMP_ERR:
1470 case CAM_AUTOSENSE_FAIL:
1471 case CAM_CMD_TIMEOUT:
1472 case CAM_UNEXP_BUSFREE:
1473 case CAM_UNCOR_PARITY:
1474 case CAM_DATA_RUN_ERR:
1475 /* decrement the number of retries */
1476 retry = ccb->ccb_h.retry_count > 0;
1477 if (retry) {
1478 ccb->ccb_h.retry_count--;
1479 error = ERESTART;
1480 } else {
1481 error = EIO;
1482 }
1483 break;
1484 case CAM_UA_ABORT:
1485 case CAM_UA_TERMIO:
1486 case CAM_MSG_REJECT_REC:
1487 /* XXX Don't know that these are correct */
1488 error = EIO;
1489 break;
1490 case CAM_SEL_TIMEOUT:
1491 {
1492 /*
1493 * XXX
1494 * A single selection timeout should not be enough
1495 * to invalidate a device. We should retry for multiple
1496 * seconds assuming this isn't a probe. We'll probably
1497 * need a special flag for that.
1498 */
1499#if 0
1500 struct cam_path *newpath;
1501
1502 /* Should we do more if we can't create the path?? */
1503 if (xpt_create_path(&newpath, xpt_path_periph(ccb->ccb_h.path),
1504 xpt_path_path_id(ccb->ccb_h.path),
1505 xpt_path_target_id(ccb->ccb_h.path),
1506 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
1507 break;
1508 /*
1509 * Let peripheral drivers know that this device has gone
1510 * away.
1511 */
1512 xpt_async(AC_LOST_DEVICE, newpath, NULL);
1513 xpt_free_path(newpath);
1514#endif
1515 error = ENXIO;
1516 break;
1517 }
1518 case CAM_REQ_INVALID:
1519 case CAM_PATH_INVALID:
1520 case CAM_DEV_NOT_THERE:
1521 case CAM_NO_HBA:
1522 case CAM_PROVIDE_FAIL:
1523 case CAM_REQ_TOO_BIG:
1524 error = EINVAL;
1525 break;
1526 case CAM_SCSI_BUS_RESET:
1527 case CAM_BDR_SENT:
1528 case CAM_REQUEUE_REQ:
1529 /* Unconditional requeue, dammit */
1530 error = ERESTART;
1531 break;
1532 case CAM_RESRC_UNAVAIL:
1533 case CAM_BUSY:
1534 /* timeout??? */
1535 default:
1536 /* decrement the number of retries */
1537 retry = ccb->ccb_h.retry_count > 0;
1538 if (retry) {
1539 ccb->ccb_h.retry_count--;
1540 error = ERESTART;
1541 } else {
1542 /* Check the sense codes */
1543 error = EIO;
1544 }
1545 break;
1546 }
1547
1548 /* Attempt a retry */
1549 if (error == ERESTART || error == 0) {
1550 if (frozen != 0)
1551 ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
1552
1553 if (error == ERESTART)
1554 xpt_action(ccb);
1555
1556 if (frozen != 0) {
1557 cam_release_devq(ccb->ccb_h.path,
1558 relsim_flags,
1559 openings,
1560 timeout,
1561 /*getcount_only*/0);
1562 }
1563 }
1564
1565
1566 return (error);
1567}
615
616 /* map the buffer into kernel memory */
617 vmapbuf(mapinfo->bp[i]);
618
619 /* set our pointer to the new mapped area */
620 *data_ptrs[i] = mapinfo->bp[i]->b_data;
621
622 mapinfo->num_bufs_used++;
623 }
624
625 return(0);
626}
627
628/*
629 * Unmap memory segments mapped into kernel virtual address space by
630 * cam_periph_mapmem().
631 */
632void
633cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo)
634{
635 int numbufs, i;
636 u_int8_t **data_ptrs[CAM_PERIPH_MAXMAPS];
637
638 if (mapinfo->num_bufs_used <= 0) {
639 /* allow ourselves to be swapped once again */
640 curproc->p_flag &= ~P_PHYSIO;
641 return;
642 }
643
644 switch (ccb->ccb_h.func_code) {
645 case XPT_DEV_MATCH:
646 numbufs = min(mapinfo->num_bufs_used, 2);
647
648 if (numbufs == 1) {
649 data_ptrs[0] = (u_int8_t **)&ccb->cdm.matches;
650 } else {
651 data_ptrs[0] = (u_int8_t **)&ccb->cdm.patterns;
652 data_ptrs[1] = (u_int8_t **)&ccb->cdm.matches;
653 }
654 break;
655 case XPT_SCSI_IO:
656 data_ptrs[0] = &ccb->csio.data_ptr;
657 numbufs = min(mapinfo->num_bufs_used, 1);
658 break;
659 default:
660 /* allow ourselves to be swapped once again */
661 curproc->p_flag &= ~P_PHYSIO;
662 return;
663 break; /* NOTREACHED */
664 }
665
666 for (i = 0; i < numbufs; i++) {
667 /* Set the user's pointer back to the original value */
668 *data_ptrs[i] = mapinfo->bp[i]->b_saveaddr;
669
670 /* unmap the buffer */
671 vunmapbuf(mapinfo->bp[i]);
672
673 /* clear the flags we set above */
674 mapinfo->bp[i]->b_flags &= ~(B_PHYS|B_BUSY);
675
676 /* release the buffer */
677 relpbuf(mapinfo->bp[i]);
678 }
679
680 /* allow ourselves to be swapped once again */
681 curproc->p_flag &= ~P_PHYSIO;
682}
683
684union ccb *
685cam_periph_getccb(struct cam_periph *periph, u_int32_t priority)
686{
687 struct ccb_hdr *ccb_h;
688 int s;
689
690 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetccb\n"));
691
692 s = splsoftcam();
693
694 while (periph->ccb_list.slh_first == NULL) {
695 if (periph->immediate_priority > priority)
696 periph->immediate_priority = priority;
697 xpt_schedule(periph, priority);
698 if ((periph->ccb_list.slh_first != NULL)
699 && (periph->ccb_list.slh_first->pinfo.priority == priority))
700 break;
701 tsleep(&periph->ccb_list, PRIBIO, "cgticb", 0);
702 }
703
704 ccb_h = periph->ccb_list.slh_first;
705 SLIST_REMOVE_HEAD(&periph->ccb_list, periph_links.sle);
706 splx(s);
707 return ((union ccb *)ccb_h);
708}
709
710void
711cam_periph_ccbwait(union ccb *ccb)
712{
713 int s;
714
715 s = splsoftcam();
716 if ((ccb->ccb_h.pinfo.index != CAM_UNQUEUED_INDEX)
717 || ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG))
718 tsleep(&ccb->ccb_h.cbfcnp, PRIBIO, "cbwait", 0);
719
720 splx(s);
721}
722
723int
724cam_periph_ioctl(struct cam_periph *periph, int cmd, caddr_t addr,
725 int (*error_routine)(union ccb *ccb,
726 cam_flags camflags,
727 u_int32_t sense_flags))
728{
729 union ccb *ccb;
730 int error;
731 int found;
732
733 error = found = 0;
734
735 switch(cmd){
736 case CAMGETPASSTHRU:
737 ccb = cam_periph_getccb(periph, /* priority */ 1);
738 xpt_setup_ccb(&ccb->ccb_h,
739 ccb->ccb_h.path,
740 /*priority*/1);
741 ccb->ccb_h.func_code = XPT_GDEVLIST;
742
743 /*
744 * Basically, the point of this is that we go through
745 * getting the list of devices, until we find a passthrough
746 * device. In the current version of the CAM code, the
747 * only way to determine what type of device we're dealing
748 * with is by its name.
749 */
750 while (found == 0) {
751 ccb->cgdl.index = 0;
752 ccb->cgdl.status = CAM_GDEVLIST_MORE_DEVS;
753 while (ccb->cgdl.status == CAM_GDEVLIST_MORE_DEVS) {
754
755 /* we want the next device in the list */
756 xpt_action(ccb);
757 if (strncmp(ccb->cgdl.periph_name,
758 "pass", 4) == 0){
759 found = 1;
760 break;
761 }
762 }
763 if ((ccb->cgdl.status == CAM_GDEVLIST_LAST_DEVICE) &&
764 (found == 0)) {
765 ccb->cgdl.periph_name[0] = '\0';
766 ccb->cgdl.unit_number = 0;
767 break;
768 }
769 }
770
771 /* copy the result back out */
772 bcopy(ccb, addr, sizeof(union ccb));
773
774 /* and release the ccb */
775 xpt_release_ccb(ccb);
776
777 break;
778 default:
779 error = ENOTTY;
780 break;
781 }
782 return(error);
783}
784
785int
786cam_periph_runccb(union ccb *ccb,
787 int (*error_routine)(union ccb *ccb,
788 cam_flags camflags,
789 u_int32_t sense_flags),
790 cam_flags camflags, u_int32_t sense_flags,
791 struct devstat *ds)
792{
793 int error;
794
795 error = 0;
796
797 /*
798 * If the user has supplied a stats structure, and if we understand
799 * this particular type of ccb, record the transaction start.
800 */
801 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
802 devstat_start_transaction(ds);
803
804 xpt_action(ccb);
805
806 do {
807 cam_periph_ccbwait(ccb);
808 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP)
809 error = 0;
810 else if (error_routine != NULL)
811 error = (*error_routine)(ccb, camflags, sense_flags);
812 else
813 error = 0;
814
815 } while (error == ERESTART);
816
817 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
818 cam_release_devq(ccb->ccb_h.path,
819 /* relsim_flags */0,
820 /* openings */0,
821 /* timeout */0,
822 /* getcount_only */ FALSE);
823
824 if ((ds != NULL) && (ccb->ccb_h.func_code == XPT_SCSI_IO))
825 devstat_end_transaction(ds,
826 ccb->csio.dxfer_len,
827 ccb->csio.tag_action & 0xf,
828 ((ccb->ccb_h.flags & CAM_DIR_MASK) ==
829 CAM_DIR_NONE) ? DEVSTAT_NO_DATA :
830 (ccb->ccb_h.flags & CAM_DIR_OUT) ?
831 DEVSTAT_WRITE :
832 DEVSTAT_READ);
833
834 return(error);
835}
836
837u_int32_t
838cam_release_devq(struct cam_path *path, u_int32_t relsim_flags,
839 u_int32_t openings, u_int32_t timeout,
840 int getcount_only)
841{
842 struct ccb_relsim crs;
843
844 xpt_setup_ccb(&crs.ccb_h, path,
845 /*priority*/1);
846 crs.ccb_h.func_code = XPT_REL_SIMQ;
847 crs.ccb_h.flags = getcount_only ? CAM_DEV_QFREEZE : 0;
848 crs.release_flags = relsim_flags;
849 crs.openings = openings;
850 crs.release_timeout = timeout;
851 xpt_action((union ccb *)&crs);
852 return (crs.qfrozen_cnt);
853}
854
855#define saved_ccb_ptr ppriv_ptr0
856static void
857camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
858{
859 cam_status status;
860 int frozen;
861 int sense;
862 struct scsi_start_stop_unit *scsi_cmd;
863 u_int32_t relsim_flags, timeout;
864 u_int32_t qfrozen_cnt;
865
866 status = done_ccb->ccb_h.status;
867 frozen = (status & CAM_DEV_QFRZN) != 0;
868 sense = (status & CAM_AUTOSNS_VALID) != 0;
869 status &= CAM_STATUS_MASK;
870
871 timeout = 0;
872 relsim_flags = 0;
873
874 /*
875 * Unfreeze the queue once if it is already frozen..
876 */
877 if (frozen != 0) {
878 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
879 /*relsim_flags*/0,
880 /*openings*/0,
881 /*timeout*/0,
882 /*getcount_only*/0);
883 }
884
885 switch (status) {
886
887 case CAM_REQ_CMP:
888
889 /*
890 * If we have successfully taken a device from the not
891 * ready to ready state, re-scan the device and re-get the
892 * inquiry information. Many devices (mostly disks) don't
893 * properly report their inquiry information unless they
894 * are spun up.
895 */
896 if (done_ccb->ccb_h.func_code == XPT_SCSI_IO) {
897 scsi_cmd = (struct scsi_start_stop_unit *)
898 &done_ccb->csio.cdb_io.cdb_bytes;
899
900 if (scsi_cmd->opcode == START_STOP_UNIT)
901 xpt_async(AC_INQ_CHANGED,
902 done_ccb->ccb_h.path, NULL);
903 }
904 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
905 sizeof(union ccb));
906
907 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
908
909 xpt_action(done_ccb);
910
911 break;
912 case CAM_SCSI_STATUS_ERROR:
913 scsi_cmd = (struct scsi_start_stop_unit *)
914 &done_ccb->csio.cdb_io.cdb_bytes;
915 if (sense != 0) {
916 struct scsi_sense_data *sense;
917 int error_code, sense_key, asc, ascq;
918
919 sense = &done_ccb->csio.sense_data;
920 scsi_extract_sense(sense, &error_code,
921 &sense_key, &asc, &ascq);
922
923 /*
924 * If the error is "invalid field in CDB",
925 * and the load/eject flag is set, turn the
926 * flag off and try again. This is just in
927 * case the drive in question barfs on the
928 * load eject flag. The CAM code should set
929 * the load/eject flag by default for
930 * removable media.
931 */
932
933 /* XXX KDM
934 * Should we check to see what the specific
935 * scsi status is?? Or does it not matter
936 * since we already know that there was an
937 * error, and we know what the specific
938 * error code was, and we know what the
939 * opcode is..
940 */
941 if ((scsi_cmd->opcode == START_STOP_UNIT) &&
942 ((scsi_cmd->how & SSS_LOEJ) != 0) &&
943 (asc == 0x24) && (ascq == 0x00) &&
944 (done_ccb->ccb_h.retry_count > 0)) {
945
946 scsi_cmd->how &= ~SSS_LOEJ;
947
948 xpt_action(done_ccb);
949
950 } else if (done_ccb->ccb_h.retry_count > 0) {
951 /*
952 * In this case, the error recovery
953 * command failed, but we've got
954 * some retries left on it. Give
955 * it another try.
956 */
957
958 /* set the timeout to .5 sec */
959 relsim_flags =
960 RELSIM_RELEASE_AFTER_TIMEOUT;
961 timeout = 500;
962
963 xpt_action(done_ccb);
964
965 break;
966
967 } else {
968 /*
969 * Copy the original CCB back and
970 * send it back to the caller.
971 */
972 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
973 done_ccb, sizeof(union ccb));
974
975 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
976
977 xpt_action(done_ccb);
978 }
979 } else {
980 /*
981 * Eh?? The command failed, but we don't
982 * have any sense. What's up with that?
983 * Fire the CCB again to return it to the
984 * caller.
985 */
986 bcopy(done_ccb->ccb_h.saved_ccb_ptr,
987 done_ccb, sizeof(union ccb));
988
989 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
990
991 xpt_action(done_ccb);
992
993 }
994 break;
995 default:
996 bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
997 sizeof(union ccb));
998
999 periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
1000
1001 xpt_action(done_ccb);
1002
1003 break;
1004 }
1005
1006 /* decrement the retry count */
1007 if (done_ccb->ccb_h.retry_count > 0)
1008 done_ccb->ccb_h.retry_count--;
1009
1010 qfrozen_cnt = cam_release_devq(done_ccb->ccb_h.path,
1011 /*relsim_flags*/relsim_flags,
1012 /*openings*/0,
1013 /*timeout*/timeout,
1014 /*getcount_only*/0);
1015}
1016
1017/*
1018 * Generic error handler. Peripheral drivers usually filter
1019 * out the errors that they handle in a unique mannor, then
1020 * call this function.
1021 */
1022int
1023cam_periph_error(union ccb *ccb, cam_flags camflags,
1024 u_int32_t sense_flags, union ccb *save_ccb)
1025{
1026 cam_status status;
1027 int frozen;
1028 int sense;
1029 int error;
1030 int openings;
1031 int retry;
1032 u_int32_t relsim_flags;
1033 u_int32_t timeout;
1034
1035 status = ccb->ccb_h.status;
1036 frozen = (status & CAM_DEV_QFRZN) != 0;
1037 sense = (status & CAM_AUTOSNS_VALID) != 0;
1038 status &= CAM_STATUS_MASK;
1039 relsim_flags = 0;
1040
1041
1042 switch (status) {
1043 case CAM_REQ_CMP:
1044 /* decrement the number of retries */
1045 retry = ccb->ccb_h.retry_count > 0;
1046 if (retry)
1047 ccb->ccb_h.retry_count--;
1048 error = 0;
1049 break;
1050 case CAM_SCSI_STATUS_ERROR:
1051
1052 switch (ccb->csio.scsi_status) {
1053 case SCSI_STATUS_OK:
1054 case SCSI_STATUS_COND_MET:
1055 case SCSI_STATUS_INTERMED:
1056 case SCSI_STATUS_INTERMED_COND_MET:
1057 error = 0;
1058 break;
1059 case SCSI_STATUS_CMD_TERMINATED:
1060 case SCSI_STATUS_CHECK_COND:
1061 if (sense != 0) {
1062 struct scsi_sense_data *sense;
1063 int error_code, sense_key, asc, ascq;
1064 struct cam_periph *periph;
1065 scsi_sense_action err_action;
1066 struct ccb_getdev cgd;
1067
1068 sense = &ccb->csio.sense_data;
1069 scsi_extract_sense(sense, &error_code,
1070 &sense_key, &asc, &ascq);
1071 periph = xpt_path_periph(ccb->ccb_h.path);
1072
1073 /*
1074 * Grab the inquiry data for this device.
1075 */
1076 xpt_setup_ccb(&cgd.ccb_h, ccb->ccb_h.path,
1077 /*priority*/ 1);
1078 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1079 xpt_action((union ccb *)&cgd);
1080
1081 err_action = scsi_error_action(asc, ascq,
1082 &cgd.inq_data);
1083
1084 /*
1085 * Send a Test Unit Ready to the device.
1086 * If the 'many' flag is set, we send 120
1087 * test unit ready commands, one every half
1088 * second. Otherwise, we just send one TUR.
1089 * We only want to do this if the retry
1090 * count has not been exhausted.
1091 */
1092 if (((err_action & SS_MASK) == SS_TUR)
1093 && save_ccb != NULL
1094 && ccb->ccb_h.retry_count > 0) {
1095
1096 /*
1097 * Since error recovery is already
1098 * in progress, don't attempt to
1099 * process this error. It is probably
1100 * related to the error that caused
1101 * the currently active error recovery
1102 * action. Also, we only have
1103 * space for one saved CCB, so if we
1104 * had two concurrent error recovery
1105 * actions, we would end up
1106 * over-writing one error recovery
1107 * CCB with another one.
1108 */
1109 if (periph->flags &
1110 CAM_PERIPH_RECOVERY_INPROG) {
1111 error = ERESTART;
1112 break;
1113 }
1114
1115 periph->flags |=
1116 CAM_PERIPH_RECOVERY_INPROG;
1117
1118 /* decrement the number of retries */
1119 if ((err_action &
1120 SSQ_DECREMENT_COUNT) != 0) {
1121 retry = 1;
1122 ccb->ccb_h.retry_count--;
1123 }
1124
1125 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1126
1127 /*
1128 * We retry this one every half
1129 * second for a minute. If the
1130 * device hasn't become ready in a
1131 * minute's time, it's unlikely to
1132 * ever become ready. If the table
1133 * doesn't specify SSQ_MANY, we can
1134 * only try this once. Oh well.
1135 */
1136 if ((err_action & SSQ_MANY) != 0)
1137 scsi_test_unit_ready(&ccb->csio,
1138 /*retries*/120,
1139 camperiphdone,
1140 MSG_SIMPLE_Q_TAG,
1141 SSD_FULL_SIZE,
1142 /*timeout*/5000);
1143 else
1144 scsi_test_unit_ready(&ccb->csio,
1145 /*retries*/1,
1146 camperiphdone,
1147 MSG_SIMPLE_Q_TAG,
1148 SSD_FULL_SIZE,
1149 /*timeout*/5000);
1150
1151 /* release the queue after .5 sec. */
1152 relsim_flags =
1153 RELSIM_RELEASE_AFTER_TIMEOUT;
1154 timeout = 500;
1155 /*
1156 * Drop the priority to 0 so that
1157 * we are the first to execute. Also
1158 * freeze the queue after this command
1159 * is sent so that we can restore the
1160 * old csio and have it queued in the
1161 * proper order before we let normal
1162 * transactions go to the drive.
1163 */
1164 ccb->ccb_h.pinfo.priority = 0;
1165 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1166
1167 /*
1168 * Save a pointer to the original
1169 * CCB in the new CCB.
1170 */
1171 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1172
1173 error = ERESTART;
1174 }
1175 /*
1176 * Send a start unit command to the device,
1177 * and then retry the command. We only
1178 * want to do this if the retry count has
1179 * not been exhausted. If the user
1180 * specified 0 retries, then we follow
1181 * their request and do not retry.
1182 */
1183 else if (((err_action & SS_MASK) == SS_START)
1184 && save_ccb != NULL
1185 && ccb->ccb_h.retry_count > 0) {
1186 int le;
1187
1188 /*
1189 * Only one error recovery action
1190 * at a time. See above.
1191 */
1192 if (periph->flags &
1193 CAM_PERIPH_RECOVERY_INPROG) {
1194 error = ERESTART;
1195 break;
1196 }
1197
1198 periph->flags |=
1199 CAM_PERIPH_RECOVERY_INPROG;
1200
1201 /* decrement the number of retries */
1202 retry = 1;
1203 ccb->ccb_h.retry_count--;
1204
1205 /*
1206 * Check for removable media and
1207 * set load/eject flag
1208 * appropriately.
1209 */
1210 if (SID_IS_REMOVABLE(&cgd.inq_data))
1211 le = TRUE;
1212 else
1213 le = FALSE;
1214
1215 /*
1216 * Attempt to start the drive up.
1217 *
1218 * Save the current ccb so it can
1219 * be restored and retried once the
1220 * drive is started up.
1221 */
1222 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1223
1224 scsi_start_stop(&ccb->csio,
1225 /*retries*/1,
1226 camperiphdone,
1227 MSG_SIMPLE_Q_TAG,
1228 /*start*/TRUE,
1229 /*load/eject*/le,
1230 /*immediate*/FALSE,
1231 SSD_FULL_SIZE,
1232 /*timeout*/50000);
1233 /*
1234 * Drop the priority to 0 so that
1235 * we are the first to execute. Also
1236 * freeze the queue after this command
1237 * is sent so that we can restore the
1238 * old csio and have it queued in the
1239 * proper order before we let normal
1240 * transactions go to the drive.
1241 */
1242 ccb->ccb_h.pinfo.priority = 0;
1243 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1244
1245 /*
1246 * Save a pointer to the original
1247 * CCB in the new CCB.
1248 */
1249 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1250
1251 error = ERESTART;
1252 } else if ((sense_flags & SF_RETRY_UA) != 0) {
1253 /*
1254 * XXX KDM this is a *horrible*
1255 * hack.
1256 */
1257 error = scsi_interpret_sense(ccb,
1258 sense_flags,
1259 &relsim_flags,
1260 &openings,
1261 &timeout,
1262 err_action);
1263 }
1264
1265 /*
1266 * Theoretically, this code should send a
1267 * test unit ready to the given device, and
1268 * if it returns and error, send a start
1269 * unit command. Since we don't yet have
1270 * the capability to do two-command error
1271 * recovery, just send a start unit.
1272 * XXX KDM fix this!
1273 */
1274 else if (((err_action & SS_MASK) == SS_TURSTART)
1275 && save_ccb != NULL
1276 && ccb->ccb_h.retry_count > 0) {
1277 int le;
1278
1279 /*
1280 * Only one error recovery action
1281 * at a time. See above.
1282 */
1283 if (periph->flags &
1284 CAM_PERIPH_RECOVERY_INPROG) {
1285 error = ERESTART;
1286 break;
1287 }
1288
1289 periph->flags |=
1290 CAM_PERIPH_RECOVERY_INPROG;
1291
1292 /* decrement the number of retries */
1293 retry = 1;
1294 ccb->ccb_h.retry_count--;
1295
1296 /*
1297 * Check for removable media and
1298 * set load/eject flag
1299 * appropriately.
1300 */
1301 if (SID_IS_REMOVABLE(&cgd.inq_data))
1302 le = TRUE;
1303 else
1304 le = FALSE;
1305
1306 /*
1307 * Attempt to start the drive up.
1308 *
1309 * Save the current ccb so it can
1310 * be restored and retried once the
1311 * drive is started up.
1312 */
1313 bcopy(ccb, save_ccb, sizeof(*save_ccb));
1314
1315 scsi_start_stop(&ccb->csio,
1316 /*retries*/1,
1317 camperiphdone,
1318 MSG_SIMPLE_Q_TAG,
1319 /*start*/TRUE,
1320 /*load/eject*/le,
1321 /*immediate*/FALSE,
1322 SSD_FULL_SIZE,
1323 /*timeout*/50000);
1324
1325 /* release the queue after .5 sec. */
1326 relsim_flags =
1327 RELSIM_RELEASE_AFTER_TIMEOUT;
1328 timeout = 500;
1329 /*
1330 * Drop the priority to 0 so that
1331 * we are the first to execute. Also
1332 * freeze the queue after this command
1333 * is sent so that we can restore the
1334 * old csio and have it queued in the
1335 * proper order before we let normal
1336 * transactions go to the drive.
1337 */
1338 ccb->ccb_h.pinfo.priority = 0;
1339 ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
1340
1341 /*
1342 * Save a pointer to the original
1343 * CCB in the new CCB.
1344 */
1345 ccb->ccb_h.saved_ccb_ptr = save_ccb;
1346
1347 error = ERESTART;
1348 } else {
1349 error = scsi_interpret_sense(ccb,
1350 sense_flags,
1351 &relsim_flags,
1352 &openings,
1353 &timeout,
1354 err_action);
1355 }
1356 } else if (ccb->csio.scsi_status ==
1357 SCSI_STATUS_CHECK_COND) {
1358 /* no point in decrementing the retry count */
1359 panic("cam_periph_error: scsi status of "
1360 "CHECK COND returned but no sense "
1361 "information is availible. "
1362 "Controller should have returned "
1363 "CAM_AUTOSENSE_FAILED");
1364 /* NOTREACHED */
1365 error = EIO;
1366 } else if (ccb->ccb_h.retry_count > 0) {
1367 /*
1368 * XXX KDM shouldn't there be a better
1369 * argument to return??
1370 */
1371 error = EIO;
1372 } else {
1373 /* decrement the number of retries */
1374 retry = ccb->ccb_h.retry_count > 0;
1375 if (retry)
1376 ccb->ccb_h.retry_count--;
1377 /*
1378 * If it was aborted with no
1379 * clue as to the reason, just
1380 * retry it again.
1381 */
1382 error = ERESTART;
1383 }
1384 break;
1385 case SCSI_STATUS_QUEUE_FULL:
1386 {
1387 /* no decrement */
1388 struct ccb_getdev cgd;
1389
1390 /*
1391 * First off, find out what the current
1392 * transaction counts are.
1393 */
1394 xpt_setup_ccb(&cgd.ccb_h,
1395 ccb->ccb_h.path,
1396 /*priority*/1);
1397 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1398 xpt_action((union ccb *)&cgd);
1399
1400 /*
1401 * If we were the only transaction active, treat
1402 * the QUEUE FULL as if it were a BUSY condition.
1403 */
1404 if (cgd.dev_active != 0) {
1405 /*
1406 * Reduce the number of openings to
1407 * be 1 less than the amount it took
1408 * to get a queue full bounded by the
1409 * minimum allowed tag count for this
1410 * device.
1411 */
1412 openings = cgd.dev_active;
1413 if (openings < cgd.mintags)
1414 openings = cgd.mintags;
1415 if (openings < cgd.dev_active+cgd.dev_openings)
1416 relsim_flags = RELSIM_ADJUST_OPENINGS;
1417 else {
1418 /*
1419 * Some devices report queue full for
1420 * temporary resource shortages. For
1421 * this reason, we allow a minimum
1422 * tag count to be entered via a
1423 * quirk entry to prevent the queue
1424 * count on these devices from falling
1425 * to a pessimisticly low value. We
1426 * still wait for the next successful
1427 * completion, however, before queueing
1428 * more transactions to the device.
1429 */
1430 relsim_flags =
1431 RELSIM_RELEASE_AFTER_CMDCMPLT;
1432 }
1433 timeout = 0;
1434 error = ERESTART;
1435 break;
1436 }
1437 /* FALLTHROUGH */
1438 }
1439 case SCSI_STATUS_BUSY:
1440 /*
1441 * Restart the queue after either another
1442 * command completes or a 1 second timeout.
1443 */
1444 /*
1445 * XXX KDM ask JTG about this again, do we need to
1446 * be looking at the retry count here?
1447 */
1448 error = ERESTART;
1449 relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT
1450 | RELSIM_RELEASE_AFTER_CMDCMPLT;
1451 timeout = 1000;
1452 break;
1453 case SCSI_STATUS_RESERV_CONFLICT:
1454 error = EIO;
1455 break;
1456 default:
1457 error = EIO;
1458 break;
1459 }
1460 break;
1461 case CAM_REQ_CMP_ERR:
1462 case CAM_AUTOSENSE_FAIL:
1463 case CAM_CMD_TIMEOUT:
1464 case CAM_UNEXP_BUSFREE:
1465 case CAM_UNCOR_PARITY:
1466 case CAM_DATA_RUN_ERR:
1467 /* decrement the number of retries */
1468 retry = ccb->ccb_h.retry_count > 0;
1469 if (retry) {
1470 ccb->ccb_h.retry_count--;
1471 error = ERESTART;
1472 } else {
1473 error = EIO;
1474 }
1475 break;
1476 case CAM_UA_ABORT:
1477 case CAM_UA_TERMIO:
1478 case CAM_MSG_REJECT_REC:
1479 /* XXX Don't know that these are correct */
1480 error = EIO;
1481 break;
1482 case CAM_SEL_TIMEOUT:
1483 {
1484 /*
1485 * XXX
1486 * A single selection timeout should not be enough
1487 * to invalidate a device. We should retry for multiple
1488 * seconds assuming this isn't a probe. We'll probably
1489 * need a special flag for that.
1490 */
1491#if 0
1492 struct cam_path *newpath;
1493
1494 /* Should we do more if we can't create the path?? */
1495 if (xpt_create_path(&newpath, xpt_path_periph(ccb->ccb_h.path),
1496 xpt_path_path_id(ccb->ccb_h.path),
1497 xpt_path_target_id(ccb->ccb_h.path),
1498 CAM_LUN_WILDCARD) != CAM_REQ_CMP)
1499 break;
1500 /*
1501 * Let peripheral drivers know that this device has gone
1502 * away.
1503 */
1504 xpt_async(AC_LOST_DEVICE, newpath, NULL);
1505 xpt_free_path(newpath);
1506#endif
1507 error = ENXIO;
1508 break;
1509 }
1510 case CAM_REQ_INVALID:
1511 case CAM_PATH_INVALID:
1512 case CAM_DEV_NOT_THERE:
1513 case CAM_NO_HBA:
1514 case CAM_PROVIDE_FAIL:
1515 case CAM_REQ_TOO_BIG:
1516 error = EINVAL;
1517 break;
1518 case CAM_SCSI_BUS_RESET:
1519 case CAM_BDR_SENT:
1520 case CAM_REQUEUE_REQ:
1521 /* Unconditional requeue, dammit */
1522 error = ERESTART;
1523 break;
1524 case CAM_RESRC_UNAVAIL:
1525 case CAM_BUSY:
1526 /* timeout??? */
1527 default:
1528 /* decrement the number of retries */
1529 retry = ccb->ccb_h.retry_count > 0;
1530 if (retry) {
1531 ccb->ccb_h.retry_count--;
1532 error = ERESTART;
1533 } else {
1534 /* Check the sense codes */
1535 error = EIO;
1536 }
1537 break;
1538 }
1539
1540 /* Attempt a retry */
1541 if (error == ERESTART || error == 0) {
1542 if (frozen != 0)
1543 ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
1544
1545 if (error == ERESTART)
1546 xpt_action(ccb);
1547
1548 if (frozen != 0) {
1549 cam_release_devq(ccb->ccb_h.path,
1550 relsim_flags,
1551 openings,
1552 timeout,
1553 /*getcount_only*/0);
1554 }
1555 }
1556
1557
1558 return (error);
1559}