xref: /freebsd/sys/cam/scsi/scsi_pt.c (revision 78007886c995898a9494648343e5236bca1cbba3)
1 /*-
2  * Implementation of SCSI Processor Target Peripheral driver for CAM.
3  *
4  * Copyright (c) 1998 Justin T. Gibbs.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer,
12  *    without modification, immediately at the beginning of the file.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/param.h>
33 #include <sys/queue.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/types.h>
37 #include <sys/bio.h>
38 #include <sys/devicestat.h>
39 #include <sys/malloc.h>
40 #include <sys/conf.h>
41 #include <sys/ptio.h>
42 
43 #include <cam/cam.h>
44 #include <cam/cam_ccb.h>
45 #include <cam/cam_periph.h>
46 #include <cam/cam_xpt_periph.h>
47 #include <cam/cam_debug.h>
48 
49 #include <cam/scsi/scsi_all.h>
50 #include <cam/scsi/scsi_message.h>
51 #include <cam/scsi/scsi_pt.h>
52 
53 #include "opt_pt.h"
54 
55 typedef enum {
56 	PT_STATE_PROBE,
57 	PT_STATE_NORMAL
58 } pt_state;
59 
60 typedef enum {
61 	PT_FLAG_NONE		= 0x00,
62 	PT_FLAG_OPEN		= 0x01,
63 	PT_FLAG_DEVICE_INVALID	= 0x02,
64 	PT_FLAG_RETRY_UA	= 0x04
65 } pt_flags;
66 
67 typedef enum {
68 	PT_CCB_BUFFER_IO	= 0x01,
69 	PT_CCB_WAITING		= 0x02,
70 	PT_CCB_RETRY_UA		= 0x04,
71 	PT_CCB_BUFFER_IO_UA	= PT_CCB_BUFFER_IO|PT_CCB_RETRY_UA
72 } pt_ccb_state;
73 
74 /* Offsets into our private area for storing information */
75 #define ccb_state	ppriv_field0
76 #define ccb_bp		ppriv_ptr1
77 
78 struct pt_softc {
79 	struct	 bio_queue_head bio_queue;
80 	struct	 devstat *device_stats;
81 	LIST_HEAD(, ccb_hdr) pending_ccbs;
82 	pt_state state;
83 	pt_flags flags;
84 	union	 ccb saved_ccb;
85 	int	 io_timeout;
86 	struct cdev *dev;
87 };
88 
89 static	d_open_t	ptopen;
90 static	d_close_t	ptclose;
91 static	d_strategy_t	ptstrategy;
92 static	periph_init_t	ptinit;
93 static	void		ptasync(void *callback_arg, u_int32_t code,
94 				struct cam_path *path, void *arg);
95 static	periph_ctor_t	ptctor;
96 static	periph_oninv_t	ptoninvalidate;
97 static	periph_dtor_t	ptdtor;
98 static	periph_start_t	ptstart;
99 static	void		ptdone(struct cam_periph *periph,
100 			       union ccb *done_ccb);
101 static	d_ioctl_t	ptioctl;
102 static  int		pterror(union ccb *ccb, u_int32_t cam_flags,
103 				u_int32_t sense_flags);
104 
105 void	scsi_send_receive(struct ccb_scsiio *csio, u_int32_t retries,
106 			  void (*cbfcnp)(struct cam_periph *, union ccb *),
107 			  u_int tag_action, int readop, u_int byte2,
108 			  u_int32_t xfer_len, u_int8_t *data_ptr,
109 			  u_int8_t sense_len, u_int32_t timeout);
110 
111 static struct periph_driver ptdriver =
112 {
113 	ptinit, "pt",
114 	TAILQ_HEAD_INITIALIZER(ptdriver.units), /* generation */ 0
115 };
116 
117 PERIPHDRIVER_DECLARE(pt, ptdriver);
118 
119 
120 static struct cdevsw pt_cdevsw = {
121 	.d_version =	D_VERSION,
122 	.d_flags =	0,
123 	.d_open =	ptopen,
124 	.d_close =	ptclose,
125 	.d_read =	physread,
126 	.d_write =	physwrite,
127 	.d_ioctl =	ptioctl,
128 	.d_strategy =	ptstrategy,
129 	.d_name =	"pt",
130 };
131 
132 #ifndef SCSI_PT_DEFAULT_TIMEOUT
133 #define SCSI_PT_DEFAULT_TIMEOUT		60
134 #endif
135 
136 static int
137 ptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
138 {
139 	struct cam_periph *periph;
140 	struct pt_softc *softc;
141 	int error = 0;
142 
143 	periph = (struct cam_periph *)dev->si_drv1;
144 	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
145 		return (ENXIO);
146 
147 	softc = (struct pt_softc *)periph->softc;
148 
149 	cam_periph_lock(periph);
150 	if (softc->flags & PT_FLAG_DEVICE_INVALID) {
151 		cam_periph_unlock(periph);
152 		cam_periph_release(periph);
153 		return(ENXIO);
154 	}
155 
156 	if ((softc->flags & PT_FLAG_OPEN) == 0)
157 		softc->flags |= PT_FLAG_OPEN;
158 	else {
159 		error = EBUSY;
160 		cam_periph_release(periph);
161 	}
162 
163 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
164 	    ("ptopen: dev=%s\n", devtoname(dev)));
165 
166 	cam_periph_unlock(periph);
167 	return (error);
168 }
169 
170 static int
171 ptclose(struct cdev *dev, int flag, int fmt, struct thread *td)
172 {
173 	struct	cam_periph *periph;
174 	struct	pt_softc *softc;
175 
176 	periph = (struct cam_periph *)dev->si_drv1;
177 	if (periph == NULL)
178 		return (ENXIO);
179 
180 	softc = (struct pt_softc *)periph->softc;
181 
182 	cam_periph_lock(periph);
183 
184 	softc->flags &= ~PT_FLAG_OPEN;
185 	cam_periph_unlock(periph);
186 	cam_periph_release(periph);
187 	return (0);
188 }
189 
190 /*
191  * Actually translate the requested transfer into one the physical driver
192  * can understand.  The transfer is described by a buf and will include
193  * only one physical transfer.
194  */
195 static void
196 ptstrategy(struct bio *bp)
197 {
198 	struct cam_periph *periph;
199 	struct pt_softc *softc;
200 
201 	periph = (struct cam_periph *)bp->bio_dev->si_drv1;
202 	bp->bio_resid = bp->bio_bcount;
203 	if (periph == NULL) {
204 		biofinish(bp, NULL, ENXIO);
205 		return;
206 	}
207 	cam_periph_lock(periph);
208 	softc = (struct pt_softc *)periph->softc;
209 
210 	/*
211 	 * If the device has been made invalid, error out
212 	 */
213 	if ((softc->flags & PT_FLAG_DEVICE_INVALID)) {
214 		cam_periph_unlock(periph);
215 		biofinish(bp, NULL, ENXIO);
216 		return;
217 	}
218 
219 	/*
220 	 * Place it in the queue of disk activities for this disk
221 	 */
222 	bioq_insert_tail(&softc->bio_queue, bp);
223 
224 	/*
225 	 * Schedule ourselves for performing the work.
226 	 */
227 	xpt_schedule(periph, /* XXX priority */1);
228 	cam_periph_unlock(periph);
229 
230 	return;
231 }
232 
233 static void
234 ptinit(void)
235 {
236 	cam_status status;
237 	struct cam_path *path;
238 
239 	/*
240 	 * Install a global async callback.  This callback will
241 	 * receive async callbacks like "new device found".
242 	 */
243 	status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
244 				 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
245 
246 	if (status == CAM_REQ_CMP) {
247 		struct ccb_setasync csa;
248 
249                 xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
250                 csa.ccb_h.func_code = XPT_SASYNC_CB;
251                 csa.event_enable = AC_FOUND_DEVICE;
252                 csa.callback = ptasync;
253                 csa.callback_arg = NULL;
254                 xpt_action((union ccb *)&csa);
255 		status = csa.ccb_h.status;
256                 xpt_free_path(path);
257         }
258 
259 	if (status != CAM_REQ_CMP) {
260 		printf("pt: Failed to attach master async callback "
261 		       "due to status 0x%x!\n", status);
262 	}
263 }
264 
265 static cam_status
266 ptctor(struct cam_periph *periph, void *arg)
267 {
268 	struct pt_softc *softc;
269 	struct ccb_setasync csa;
270 	struct ccb_getdev *cgd;
271 
272 	cgd = (struct ccb_getdev *)arg;
273 	if (periph == NULL) {
274 		printf("ptregister: periph was NULL!!\n");
275 		return(CAM_REQ_CMP_ERR);
276 	}
277 
278 	if (cgd == NULL) {
279 		printf("ptregister: no getdev CCB, can't register device\n");
280 		return(CAM_REQ_CMP_ERR);
281 	}
282 
283 	softc = (struct pt_softc *)malloc(sizeof(*softc),M_DEVBUF,M_NOWAIT);
284 
285 	if (softc == NULL) {
286 		printf("daregister: Unable to probe new device. "
287 		       "Unable to allocate softc\n");
288 		return(CAM_REQ_CMP_ERR);
289 	}
290 
291 	bzero(softc, sizeof(*softc));
292 	LIST_INIT(&softc->pending_ccbs);
293 	softc->state = PT_STATE_NORMAL;
294 	bioq_init(&softc->bio_queue);
295 
296 	softc->io_timeout = SCSI_PT_DEFAULT_TIMEOUT * 1000;
297 
298 	periph->softc = softc;
299 
300 	softc->device_stats = devstat_new_entry("pt",
301 			  periph->unit_number, 0,
302 			  DEVSTAT_NO_BLOCKSIZE,
303 			  SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI,
304 			  DEVSTAT_PRIORITY_OTHER);
305 
306 	cam_periph_unlock(periph);
307 	softc->dev = make_dev(&pt_cdevsw, periph->unit_number, UID_ROOT,
308 			      GID_OPERATOR, 0600, "%s%d", periph->periph_name,
309 			      periph->unit_number);
310 	cam_periph_lock(periph);
311 	softc->dev->si_drv1 = periph;
312 
313 	/*
314 	 * Add async callbacks for bus reset and
315 	 * bus device reset calls.  I don't bother
316 	 * checking if this fails as, in most cases,
317 	 * the system will function just fine without
318 	 * them and the only alternative would be to
319 	 * not attach the device on failure.
320 	 */
321 	xpt_setup_ccb(&csa.ccb_h, periph->path, /*priority*/5);
322 	csa.ccb_h.func_code = XPT_SASYNC_CB;
323 	csa.event_enable = AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE;
324 	csa.callback = ptasync;
325 	csa.callback_arg = periph;
326 	xpt_action((union ccb *)&csa);
327 
328 	/* Tell the user we've attached to the device */
329 	xpt_announce_periph(periph, NULL);
330 
331 	return(CAM_REQ_CMP);
332 }
333 
334 static void
335 ptoninvalidate(struct cam_periph *periph)
336 {
337 	struct pt_softc *softc;
338 	struct ccb_setasync csa;
339 
340 	softc = (struct pt_softc *)periph->softc;
341 
342 	/*
343 	 * De-register any async callbacks.
344 	 */
345 	xpt_setup_ccb(&csa.ccb_h, periph->path,
346 		      /* priority */ 5);
347 	csa.ccb_h.func_code = XPT_SASYNC_CB;
348 	csa.event_enable = 0;
349 	csa.callback = ptasync;
350 	csa.callback_arg = periph;
351 	xpt_action((union ccb *)&csa);
352 
353 	softc->flags |= PT_FLAG_DEVICE_INVALID;
354 
355 	/*
356 	 * Return all queued I/O with ENXIO.
357 	 * XXX Handle any transactions queued to the card
358 	 *     with XPT_ABORT_CCB.
359 	 */
360 	bioq_flush(&softc->bio_queue, NULL, ENXIO);
361 
362 	xpt_print(periph->path, "lost device\n");
363 }
364 
365 static void
366 ptdtor(struct cam_periph *periph)
367 {
368 	struct pt_softc *softc;
369 
370 	softc = (struct pt_softc *)periph->softc;
371 
372 	devstat_remove_entry(softc->device_stats);
373 
374 	destroy_dev(softc->dev);
375 
376 	xpt_print(periph->path, "removing device entry\n");
377 	free(softc, M_DEVBUF);
378 }
379 
380 static void
381 ptasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg)
382 {
383 	struct cam_periph *periph;
384 
385 	periph = (struct cam_periph *)callback_arg;
386 	switch (code) {
387 	case AC_FOUND_DEVICE:
388 	{
389 		struct ccb_getdev *cgd;
390 		cam_status status;
391 
392 		cgd = (struct ccb_getdev *)arg;
393 		if (cgd == NULL)
394 			break;
395 
396 		if (SID_TYPE(&cgd->inq_data) != T_PROCESSOR)
397 			break;
398 
399 		/*
400 		 * Allocate a peripheral instance for
401 		 * this device and start the probe
402 		 * process.
403 		 */
404 		status = cam_periph_alloc(ptctor, ptoninvalidate, ptdtor,
405 					  ptstart, "pt", CAM_PERIPH_BIO,
406 					  cgd->ccb_h.path, ptasync,
407 					  AC_FOUND_DEVICE, cgd);
408 
409 		if (status != CAM_REQ_CMP
410 		 && status != CAM_REQ_INPROG)
411 			printf("ptasync: Unable to attach to new device "
412 				"due to status 0x%x\n", status);
413 		break;
414 	}
415 	case AC_SENT_BDR:
416 	case AC_BUS_RESET:
417 	{
418 		struct pt_softc *softc;
419 		struct ccb_hdr *ccbh;
420 
421 		softc = (struct pt_softc *)periph->softc;
422 		/*
423 		 * Don't fail on the expected unit attention
424 		 * that will occur.
425 		 */
426 		softc->flags |= PT_FLAG_RETRY_UA;
427 		LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
428 			ccbh->ccb_state |= PT_CCB_RETRY_UA;
429 	}
430 	/* FALLTHROUGH */
431 	default:
432 		cam_periph_async(periph, code, path, arg);
433 		break;
434 	}
435 }
436 
437 static void
438 ptstart(struct cam_periph *periph, union ccb *start_ccb)
439 {
440 	struct pt_softc *softc;
441 	struct bio *bp;
442 
443 	softc = (struct pt_softc *)periph->softc;
444 
445 	/*
446 	 * See if there is a buf with work for us to do..
447 	 */
448 	bp = bioq_first(&softc->bio_queue);
449 	if (periph->immediate_priority <= periph->pinfo.priority) {
450 		CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
451 				("queuing for immediate ccb\n"));
452 		start_ccb->ccb_h.ccb_state = PT_CCB_WAITING;
453 		SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
454 				  periph_links.sle);
455 		periph->immediate_priority = CAM_PRIORITY_NONE;
456 		wakeup(&periph->ccb_list);
457 	} else if (bp == NULL) {
458 		xpt_release_ccb(start_ccb);
459 	} else {
460 		bioq_remove(&softc->bio_queue, bp);
461 
462 		devstat_start_transaction_bio(softc->device_stats, bp);
463 
464 		scsi_send_receive(&start_ccb->csio,
465 				  /*retries*/4,
466 				  ptdone,
467 				  MSG_SIMPLE_Q_TAG,
468 				  bp->bio_cmd == BIO_READ,
469 				  /*byte2*/0,
470 				  bp->bio_bcount,
471 				  bp->bio_data,
472 				  /*sense_len*/SSD_FULL_SIZE,
473 				  /*timeout*/softc->io_timeout);
474 
475 		start_ccb->ccb_h.ccb_state = PT_CCB_BUFFER_IO_UA;
476 
477 		/*
478 		 * Block out any asyncronous callbacks
479 		 * while we touch the pending ccb list.
480 		 */
481 		LIST_INSERT_HEAD(&softc->pending_ccbs, &start_ccb->ccb_h,
482 				 periph_links.le);
483 
484 		start_ccb->ccb_h.ccb_bp = bp;
485 		bp = bioq_first(&softc->bio_queue);
486 
487 		xpt_action(start_ccb);
488 
489 		if (bp != NULL) {
490 			/* Have more work to do, so ensure we stay scheduled */
491 			xpt_schedule(periph, /* XXX priority */1);
492 		}
493 	}
494 }
495 
496 static void
497 ptdone(struct cam_periph *periph, union ccb *done_ccb)
498 {
499 	struct pt_softc *softc;
500 	struct ccb_scsiio *csio;
501 
502 	softc = (struct pt_softc *)periph->softc;
503 	csio = &done_ccb->csio;
504 	switch (csio->ccb_h.ccb_state) {
505 	case PT_CCB_BUFFER_IO:
506 	case PT_CCB_BUFFER_IO_UA:
507 	{
508 		struct bio *bp;
509 
510 		bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
511 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
512 			int error;
513 			int sf;
514 
515 			if ((csio->ccb_h.ccb_state & PT_CCB_RETRY_UA) != 0)
516 				sf = SF_RETRY_UA;
517 			else
518 				sf = 0;
519 
520 			error = pterror(done_ccb, CAM_RETRY_SELTO, sf);
521 			if (error == ERESTART) {
522 				/*
523 				 * A retry was scheuled, so
524 				 * just return.
525 				 */
526 				return;
527 			}
528 			if (error != 0) {
529 				if (error == ENXIO) {
530 					/*
531 					 * Catastrophic error.  Mark our device
532 					 * as invalid.
533 					 */
534 					xpt_print(periph->path,
535 					    "Invalidating device\n");
536 					softc->flags |= PT_FLAG_DEVICE_INVALID;
537 				}
538 
539 				/*
540 				 * return all queued I/O with EIO, so that
541 				 * the client can retry these I/Os in the
542 				 * proper order should it attempt to recover.
543 				 */
544 				bioq_flush(&softc->bio_queue, NULL, EIO);
545 				bp->bio_error = error;
546 				bp->bio_resid = bp->bio_bcount;
547 				bp->bio_flags |= BIO_ERROR;
548 			} else {
549 				bp->bio_resid = csio->resid;
550 				bp->bio_error = 0;
551 				if (bp->bio_resid != 0) {
552 					/* Short transfer ??? */
553 					bp->bio_flags |= BIO_ERROR;
554 				}
555 			}
556 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
557 				cam_release_devq(done_ccb->ccb_h.path,
558 						 /*relsim_flags*/0,
559 						 /*reduction*/0,
560 						 /*timeout*/0,
561 						 /*getcount_only*/0);
562 		} else {
563 			bp->bio_resid = csio->resid;
564 			if (bp->bio_resid != 0)
565 				bp->bio_flags |= BIO_ERROR;
566 		}
567 
568 		/*
569 		 * Block out any asyncronous callbacks
570 		 * while we touch the pending ccb list.
571 		 */
572 		LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
573 
574 		biofinish(bp, softc->device_stats, 0);
575 		break;
576 	}
577 	case PT_CCB_WAITING:
578 		/* Caller will release the CCB */
579 		wakeup(&done_ccb->ccb_h.cbfcnp);
580 		return;
581 	}
582 	xpt_release_ccb(done_ccb);
583 }
584 
585 static int
586 pterror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
587 {
588 	struct pt_softc	  *softc;
589 	struct cam_periph *periph;
590 
591 	periph = xpt_path_periph(ccb->ccb_h.path);
592 	softc = (struct pt_softc *)periph->softc;
593 
594 	return(cam_periph_error(ccb, cam_flags, sense_flags,
595 				&softc->saved_ccb));
596 }
597 
598 static int
599 ptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
600 {
601 	struct cam_periph *periph;
602 	struct pt_softc *softc;
603 	int error = 0;
604 
605 	periph = (struct cam_periph *)dev->si_drv1;
606 	if (periph == NULL)
607 		return(ENXIO);
608 
609 	softc = (struct pt_softc *)periph->softc;
610 
611 	cam_periph_lock(periph);
612 
613 	switch(cmd) {
614 	case PTIOCGETTIMEOUT:
615 		if (softc->io_timeout >= 1000)
616 			*(int *)addr = softc->io_timeout / 1000;
617 		else
618 			*(int *)addr = 0;
619 		break;
620 	case PTIOCSETTIMEOUT:
621 		if (*(int *)addr < 1) {
622 			error = EINVAL;
623 			break;
624 		}
625 
626 		softc->io_timeout = *(int *)addr * 1000;
627 
628 		break;
629 	default:
630 		error = cam_periph_ioctl(periph, cmd, addr, pterror);
631 		break;
632 	}
633 
634 	cam_periph_unlock(periph);
635 
636 	return(error);
637 }
638 
639 void
640 scsi_send_receive(struct ccb_scsiio *csio, u_int32_t retries,
641 		  void (*cbfcnp)(struct cam_periph *, union ccb *),
642 		  u_int tag_action, int readop, u_int byte2,
643 		  u_int32_t xfer_len, u_int8_t *data_ptr, u_int8_t sense_len,
644 		  u_int32_t timeout)
645 {
646 	struct scsi_send_receive *scsi_cmd;
647 
648 	scsi_cmd = (struct scsi_send_receive *)&csio->cdb_io.cdb_bytes;
649 	scsi_cmd->opcode = readop ? RECEIVE : SEND;
650 	scsi_cmd->byte2 = byte2;
651 	scsi_ulto3b(xfer_len, scsi_cmd->xfer_len);
652 	scsi_cmd->control = 0;
653 
654 	cam_fill_csio(csio,
655 		      retries,
656 		      cbfcnp,
657 		      /*flags*/readop ? CAM_DIR_IN : CAM_DIR_OUT,
658 		      tag_action,
659 		      data_ptr,
660 		      xfer_len,
661 		      sense_len,
662 		      sizeof(*scsi_cmd),
663 		      timeout);
664 }
665