scsi_target.c revision 62828
1/*
2 * Implementation of a simple Target Mode SCSI Proccessor Target driver for CAM.
3 *
4 * Copyright (c) 1998, 1999 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 * $FreeBSD: head/sys/cam/scsi/scsi_target.c 62828 2000-07-08 23:24:08Z mjacob $
29 */
30#include <stddef.h>	/* For offsetof */
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/conf.h>
39#include <sys/devicestat.h>
40#include <sys/malloc.h>
41#include <sys/poll.h>
42#include <sys/select.h>	/* For struct selinfo. */
43#include <sys/uio.h>
44
45#include <cam/cam.h>
46#include <cam/cam_ccb.h>
47#include <cam/cam_extend.h>
48#include <cam/cam_periph.h>
49#include <cam/cam_queue.h>
50#include <cam/cam_xpt_periph.h>
51#include <cam/cam_debug.h>
52
53#include <cam/scsi/scsi_all.h>
54#include <cam/scsi/scsi_pt.h>
55#include <cam/scsi/scsi_targetio.h>
56#include <cam/scsi/scsi_message.h>
57
58typedef enum {
59	TARG_STATE_NORMAL,
60	TARG_STATE_EXCEPTION,
61	TARG_STATE_TEARDOWN
62} targ_state;
63
64typedef enum {
65	TARG_FLAG_NONE		 = 0x00,
66	TARG_FLAG_SEND_EOF	 = 0x01,
67	TARG_FLAG_RECEIVE_EOF	 = 0x02,
68	TARG_FLAG_LUN_ENABLED	 = 0x04
69} targ_flags;
70
71typedef enum {
72	TARG_CCB_NONE		= 0x00,
73	TARG_CCB_WAITING	= 0x01,
74	TARG_CCB_HELDQ		= 0x02,
75	TARG_CCB_ABORT_TO_HELDQ = 0x04
76} targ_ccb_flags;
77
78#define MAX_ACCEPT	16
79#define MAX_IMMEDIATE	16
80#define MAX_BUF_SIZE	256	/* Max inquiry/sense/mode page transfer */
81#define MAX_INITIATORS	256	/* includes widest fibre channel for now */
82
83#define MIN(a, b) ((a > b) ? b : a)
84
85#define TARG_CONTROL_UNIT 0xffff00ff
86#define TARG_IS_CONTROL_DEV(unit) ((unit) == TARG_CONTROL_UNIT)
87
88#define TARG_TAG_WILDCARD ((u_int)~0)
89
90/* Offsets into our private CCB area for storing accept information */
91#define ccb_flags	ppriv_field0
92#define ccb_descr	ppriv_ptr1
93
94/* We stick a pointer to the originating accept TIO in each continue I/O CCB */
95#define ccb_atio	ppriv_ptr1
96
97struct targ_softc {
98	/* CTIOs pending on the controller */
99	struct		ccb_queue pending_queue;
100
101	/* ATIOs awaiting CTIO resources from the XPT */
102	struct		ccb_queue work_queue;
103
104	/*
105	 * ATIOs for SEND operations waiting for 'write'
106	 * buffer resources from our userland daemon.
107	 */
108	struct		ccb_queue snd_ccb_queue;
109
110	/*
111	 * ATIOs for RCV operations waiting for 'read'
112	 * buffer resources from our userland daemon.
113	 */
114	struct		ccb_queue rcv_ccb_queue;
115
116	/*
117	 * ATIOs for commands unknown to the kernel driver.
118	 * These are queued for the userland daemon to
119	 * consume.
120	 */
121	struct		ccb_queue unknown_atio_queue;
122
123	/*
124	 * Userland buffers for SEND commands waiting for
125	 * SEND ATIOs to be queued by an initiator.
126	 */
127	struct		bio_queue_head snd_bio_queue;
128
129	/*
130	 * Userland buffers for RCV commands waiting for
131	 * RCV ATIOs to be queued by an initiator.
132	 */
133	struct		bio_queue_head rcv_bio_queue;
134	struct		devstat device_stats;
135	dev_t		targ_dev;
136	struct		selinfo snd_select;
137	struct		selinfo rcv_select;
138	targ_state	state;
139	targ_flags	flags;
140	targ_exception	exceptions;
141	u_int		init_level;
142	u_int		inq_data_len;
143	struct		scsi_inquiry_data *inq_data;
144	struct		ccb_accept_tio *accept_tio_list;
145	struct		ccb_hdr_slist immed_notify_slist;
146	struct		initiator_state istate[MAX_INITIATORS];
147};
148
149struct targ_cmd_desc {
150	struct	  ccb_accept_tio* atio_link;
151	u_int	  data_resid;	/* How much left to transfer */
152	u_int	  data_increment;/* Amount to send before next disconnect */
153	void*	  data;		/* The data. Can be from backing_store or not */
154	void*	  backing_store;/* Backing store allocated for this descriptor*/
155	struct	  bio *bp;	/* Buffer for this transfer */
156	u_int	  max_size;	/* Size of backing_store */
157	u_int32_t timeout;
158	u_int8_t  status;	/* Status to return to initiator */
159};
160
161static	d_open_t	targopen;
162static	d_close_t	targclose;
163static	d_read_t	targread;
164static	d_write_t	targwrite;
165static	d_ioctl_t	targioctl;
166static	d_poll_t	targpoll;
167static	d_strategy_t	targstrategy;
168
169#define TARG_CDEV_MAJOR	65
170static struct cdevsw targ_cdevsw = {
171	/* open */	targopen,
172	/* close */	targclose,
173	/* read */	targread,
174	/* write */	targwrite,
175	/* ioctl */	targioctl,
176	/* poll */	targpoll,
177	/* mmap */	nommap,
178	/* strategy */	targstrategy,
179	/* name */	"targ",
180	/* maj */	TARG_CDEV_MAJOR,
181	/* dump */	nodump,
182	/* psize */	nopsize,
183	/* flags */	0,
184	/* bmaj */	-1
185};
186
187static int		targsendccb(struct cam_periph *periph, union ccb *ccb,
188				    union ccb *inccb);
189static periph_init_t	targinit;
190static void		targasync(void *callback_arg, u_int32_t code,
191				struct cam_path *path, void *arg);
192static int		targallocinstance(struct ioc_alloc_unit *alloc_unit);
193static int		targfreeinstance(struct ioc_alloc_unit *alloc_unit);
194static cam_status	targenlun(struct cam_periph *periph);
195static cam_status	targdislun(struct cam_periph *periph);
196static periph_ctor_t	targctor;
197static periph_dtor_t	targdtor;
198static void		targrunqueue(struct cam_periph *periph,
199				     struct targ_softc *softc);
200static periph_start_t	targstart;
201static void		targdone(struct cam_periph *periph,
202				 union ccb *done_ccb);
203static void		targfireexception(struct cam_periph *periph,
204					  struct targ_softc *softc);
205static void		targinoterror(struct cam_periph *periph,
206				      struct targ_softc *softc,
207				      struct ccb_immed_notify *inot);
208static  int		targerror(union ccb *ccb, u_int32_t cam_flags,
209				  u_int32_t sense_flags);
210static struct targ_cmd_desc*	allocdescr(void);
211static void		freedescr(struct targ_cmd_desc *buf);
212static void		fill_sense(struct targ_softc *softc,
213				   u_int initiator_id, u_int error_code,
214				   u_int sense_key, u_int asc, u_int ascq);
215static void		copy_sense(struct targ_softc *softc,
216				   struct initiator_state *istate,
217				   u_int8_t *sense_buffer, size_t sense_len);
218static void	set_unit_attention_cond(struct cam_periph *periph,
219					u_int initiator_id, ua_types ua);
220static void	set_ca_condition(struct cam_periph *periph,
221				 u_int initiator_id, ca_types ca);
222static void	abort_pending_transactions(struct cam_periph *periph,
223					   u_int initiator_id, u_int tag_id,
224					   int errno, int to_held_queue);
225
226static struct periph_driver targdriver =
227{
228	targinit, "targ",
229	TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0
230};
231
232DATA_SET(periphdriver_set, targdriver);
233
234static struct extend_array *targperiphs;
235static dev_t targ_ctl_dev;
236
237static void
238targinit(void)
239{
240	/*
241	 * Create our extend array for storing the devices we attach to.
242	 */
243	targperiphs = cam_extend_new();
244	if (targperiphs == NULL) {
245		printf("targ: Failed to alloc extend array!\n");
246		return;
247	}
248	targ_ctl_dev = make_dev(&targ_cdevsw, TARG_CONTROL_UNIT, UID_ROOT,
249	    GID_OPERATOR, 0600, "%s.ctl", "targ");
250	if (targ_ctl_dev == (dev_t) 0) {
251		printf("targ: failed to create control dev\n");
252	}
253}
254
255static void
256targasync(void *callback_arg, u_int32_t code,
257	  struct cam_path *path, void *arg)
258{
259	struct cam_periph *periph;
260	struct targ_softc *softc;
261
262	periph = (struct cam_periph *)callback_arg;
263	softc = (struct targ_softc *)periph->softc;
264	switch (code) {
265	case AC_PATH_DEREGISTERED:
266	{
267		/* XXX Implement */
268		break;
269	}
270	default:
271		break;
272	}
273}
274
275/* Attempt to enable our lun */
276static cam_status
277targenlun(struct cam_periph *periph)
278{
279	union ccb immed_ccb;
280	struct targ_softc *softc;
281	cam_status status;
282	int i;
283
284	softc = (struct targ_softc *)periph->softc;
285
286	if ((softc->flags & TARG_FLAG_LUN_ENABLED) != 0)
287		return (CAM_REQ_CMP);
288
289	xpt_setup_ccb(&immed_ccb.ccb_h, periph->path, /*priority*/1);
290	immed_ccb.ccb_h.func_code = XPT_EN_LUN;
291
292	/* Don't need support for any vendor specific commands */
293	immed_ccb.cel.grp6_len = 0;
294	immed_ccb.cel.grp7_len = 0;
295	immed_ccb.cel.enable = 1;
296	xpt_action(&immed_ccb);
297	status = immed_ccb.ccb_h.status;
298	if (status != CAM_REQ_CMP) {
299		xpt_print_path(periph->path);
300		printf("targenlun - Enable Lun Rejected with status 0x%x\n",
301		       status);
302		return (status);
303	}
304
305	softc->flags |= TARG_FLAG_LUN_ENABLED;
306
307	/*
308	 * Build up a buffer of accept target I/O
309	 * operations for incoming selections.
310	 */
311	for (i = 0; i < MAX_ACCEPT; i++) {
312		struct ccb_accept_tio *atio;
313
314		atio = (struct ccb_accept_tio*)malloc(sizeof(*atio), M_DEVBUF,
315						      M_NOWAIT);
316		if (atio == NULL) {
317			status = CAM_RESRC_UNAVAIL;
318			break;
319		}
320
321		atio->ccb_h.ccb_descr = allocdescr();
322
323		if (atio->ccb_h.ccb_descr == NULL) {
324			free(atio, M_DEVBUF);
325			status = CAM_RESRC_UNAVAIL;
326			break;
327		}
328
329		xpt_setup_ccb(&atio->ccb_h, periph->path, /*priority*/1);
330		atio->ccb_h.func_code = XPT_ACCEPT_TARGET_IO;
331		atio->ccb_h.cbfcnp = targdone;
332		atio->ccb_h.ccb_flags = TARG_CCB_NONE;
333		xpt_action((union ccb *)atio);
334		status = atio->ccb_h.status;
335		if (status != CAM_REQ_INPROG) {
336			xpt_print_path(periph->path);
337			printf("Queue of atio failed\n");
338			freedescr(atio->ccb_h.ccb_descr);
339			free(atio, M_DEVBUF);
340			break;
341		}
342		((struct targ_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link =
343		    softc->accept_tio_list;
344		softc->accept_tio_list = atio;
345	}
346
347	if (i == 0) {
348		xpt_print_path(periph->path);
349		printf("targenlun - Could not allocate accept tio CCBs: "
350		       "status = 0x%x\n", status);
351		targdislun(periph);
352		return (CAM_REQ_CMP_ERR);
353	}
354
355	/*
356	 * Build up a buffer of immediate notify CCBs
357	 * so the SIM can tell us of asynchronous target mode events.
358	 */
359	for (i = 0; i < MAX_ACCEPT; i++) {
360		struct ccb_immed_notify *inot;
361
362		inot = (struct ccb_immed_notify*)malloc(sizeof(*inot), M_DEVBUF,
363						        M_NOWAIT);
364
365		if (inot == NULL) {
366			status = CAM_RESRC_UNAVAIL;
367			break;
368		}
369
370		xpt_setup_ccb(&inot->ccb_h, periph->path, /*priority*/1);
371		inot->ccb_h.func_code = XPT_IMMED_NOTIFY;
372		inot->ccb_h.cbfcnp = targdone;
373		SLIST_INSERT_HEAD(&softc->immed_notify_slist, &inot->ccb_h,
374				  periph_links.sle);
375		xpt_action((union ccb *)inot);
376	}
377
378	if (i == 0) {
379		xpt_print_path(periph->path);
380		printf("targenlun - Could not allocate immediate notify CCBs: "
381		       "status = 0x%x\n", status);
382		targdislun(periph);
383		return (CAM_REQ_CMP_ERR);
384	}
385
386	return (CAM_REQ_CMP);
387}
388
389static cam_status
390targdislun(struct cam_periph *periph)
391{
392	union ccb ccb;
393	struct targ_softc *softc;
394	struct ccb_accept_tio* atio;
395	struct ccb_hdr *ccb_h;
396
397	softc = (struct targ_softc *)periph->softc;
398	if ((softc->flags & TARG_FLAG_LUN_ENABLED) == 0)
399		return CAM_REQ_CMP;
400
401	/* XXX Block for Continue I/O completion */
402
403	/* Kill off all ACCECPT and IMMEDIATE CCBs */
404	while ((atio = softc->accept_tio_list) != NULL) {
405
406		softc->accept_tio_list =
407		    ((struct targ_cmd_desc*)atio->ccb_h.ccb_descr)->atio_link;
408		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1);
409		ccb.cab.ccb_h.func_code = XPT_ABORT;
410		ccb.cab.abort_ccb = (union ccb *)atio;
411		xpt_action(&ccb);
412	}
413
414	while ((ccb_h = SLIST_FIRST(&softc->immed_notify_slist)) != NULL) {
415		SLIST_REMOVE_HEAD(&softc->immed_notify_slist, periph_links.sle);
416		xpt_setup_ccb(&ccb.cab.ccb_h, periph->path, /*priority*/1);
417		ccb.cab.ccb_h.func_code = XPT_ABORT;
418		ccb.cab.abort_ccb = (union ccb *)ccb_h;
419		xpt_action(&ccb);
420	}
421
422	/*
423	 * Dissable this lun.
424	 */
425	xpt_setup_ccb(&ccb.cel.ccb_h, periph->path, /*priority*/1);
426	ccb.cel.ccb_h.func_code = XPT_EN_LUN;
427	ccb.cel.enable = 0;
428	xpt_action(&ccb);
429
430	if (ccb.cel.ccb_h.status != CAM_REQ_CMP)
431		printf("targdislun - Disabling lun on controller failed "
432		       "with status 0x%x\n", ccb.cel.ccb_h.status);
433	else
434		softc->flags &= ~TARG_FLAG_LUN_ENABLED;
435	return (ccb.cel.ccb_h.status);
436}
437
438static cam_status
439targctor(struct cam_periph *periph, void *arg)
440{
441	struct ccb_pathinq *cpi;
442	struct targ_softc *softc;
443	int i;
444
445	cpi = (struct ccb_pathinq *)arg;
446
447	/* Allocate our per-instance private storage */
448	softc = (struct targ_softc *)malloc(sizeof(*softc), M_DEVBUF, M_NOWAIT);
449	if (softc == NULL) {
450		printf("targctor: unable to malloc softc\n");
451		return (CAM_REQ_CMP_ERR);
452	}
453
454	bzero(softc, sizeof(*softc));
455	TAILQ_INIT(&softc->pending_queue);
456	TAILQ_INIT(&softc->work_queue);
457	TAILQ_INIT(&softc->snd_ccb_queue);
458	TAILQ_INIT(&softc->rcv_ccb_queue);
459	TAILQ_INIT(&softc->unknown_atio_queue);
460	bioq_init(&softc->snd_bio_queue);
461	bioq_init(&softc->rcv_bio_queue);
462	softc->accept_tio_list = NULL;
463	SLIST_INIT(&softc->immed_notify_slist);
464	softc->state = TARG_STATE_NORMAL;
465	periph->softc = softc;
466	softc->init_level++;
467
468	cam_extend_set(targperiphs, periph->unit_number, periph);
469
470	/*
471	 * We start out life with a UA to indicate power-on/reset.
472	 */
473	for (i = 0; i < MAX_INITIATORS; i++)
474		softc->istate[i].pending_ua = UA_POWER_ON;
475
476	/*
477	 * Allocate an initial inquiry data buffer.  We might allow the
478	 * user to override this later via an ioctl.
479	 */
480	softc->inq_data_len = sizeof(*softc->inq_data);
481	softc->inq_data = malloc(softc->inq_data_len, M_DEVBUF, M_NOWAIT);
482	if (softc->inq_data == NULL) {
483		printf("targctor - Unable to malloc inquiry data\n");
484		targdtor(periph);
485		return (CAM_RESRC_UNAVAIL);
486	}
487	bzero(softc->inq_data, softc->inq_data_len);
488	softc->inq_data->device = T_PROCESSOR | (SID_QUAL_LU_CONNECTED << 5);
489	softc->inq_data->version = 2;
490	softc->inq_data->response_format = 2; /* SCSI2 Inquiry Format */
491	softc->inq_data->flags =
492	    cpi->hba_inquiry & (PI_SDTR_ABLE|PI_WIDE_16|PI_WIDE_32);
493	softc->inq_data->additional_length = softc->inq_data_len - 4;
494	strncpy(softc->inq_data->vendor, "FreeBSD ", SID_VENDOR_SIZE);
495	strncpy(softc->inq_data->product, "TM-PT           ", SID_PRODUCT_SIZE);
496	strncpy(softc->inq_data->revision, "0.0 ", SID_REVISION_SIZE);
497	softc->targ_dev = make_dev(&targ_cdevsw, periph->unit_number, UID_ROOT,
498				   GID_OPERATOR, 0600, "%s%d",
499				   periph->periph_name, periph->unit_number);
500	softc->init_level++;
501	return (CAM_REQ_CMP);
502}
503
504static void
505targdtor(struct cam_periph *periph)
506{
507	struct targ_softc *softc;
508
509	softc = (struct targ_softc *)periph->softc;
510
511	softc->state = TARG_STATE_TEARDOWN;
512
513	targdislun(periph);
514
515	cam_extend_release(targperiphs, periph->unit_number);
516
517	switch (softc->init_level) {
518	default:
519		/* FALLTHROUGH */
520	case 2:
521		free(softc->inq_data, M_DEVBUF);
522		destroy_dev(softc->targ_dev);
523		/* FALLTHROUGH */
524	case 1:
525		free(softc, M_DEVBUF);
526		break;
527	case 0:
528		panic("targdtor - impossible init level");;
529	}
530}
531
532static int
533targopen(dev_t dev, int flags, int fmt, struct proc *p)
534{
535	struct cam_periph *periph;
536	struct	targ_softc *softc;
537	u_int unit;
538	cam_status status;
539	int error;
540	int s;
541
542	unit = minor(dev);
543
544	/* An open of the control device always succeeds */
545	if (TARG_IS_CONTROL_DEV(unit))
546		return 0;
547
548	s = splsoftcam();
549	periph = cam_extend_get(targperiphs, unit);
550	if (periph == NULL) {
551		return (ENXIO);
552        	splx(s);
553	}
554	if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) {
555		splx(s);
556		return (error);
557	}
558
559	softc = (struct targ_softc *)periph->softc;
560	if ((softc->flags & TARG_FLAG_LUN_ENABLED) == 0) {
561		if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
562			splx(s);
563			cam_periph_unlock(periph);
564			return(ENXIO);
565		}
566	}
567        splx(s);
568
569	status = targenlun(periph);
570	switch (status) {
571	case CAM_REQ_CMP:
572		error = 0;
573		break;
574	case CAM_RESRC_UNAVAIL:
575		error = ENOMEM;
576		break;
577	case CAM_LUN_ALRDY_ENA:
578		error = EADDRINUSE;
579		break;
580	default:
581		error = ENXIO;
582		break;
583	}
584        cam_periph_unlock(periph);
585	if (error) {
586		cam_periph_release(periph);
587	}
588	return (error);
589}
590
591static int
592targclose(dev_t dev, int flag, int fmt, struct proc *p)
593{
594	struct	cam_periph *periph;
595	struct	targ_softc *softc;
596	u_int	unit;
597	int	s;
598	int	error;
599
600	unit = minor(dev);
601
602	/* A close of the control device always succeeds */
603	if (TARG_IS_CONTROL_DEV(unit))
604		return 0;
605
606	s = splsoftcam();
607	periph = cam_extend_get(targperiphs, unit);
608	if (periph == NULL) {
609		splx(s);
610		return (ENXIO);
611	}
612	if ((error = cam_periph_lock(periph, PRIBIO)) != 0)
613		return (error);
614	softc = (struct targ_softc *)periph->softc;
615	splx(s);
616
617	targdislun(periph);
618
619	cam_periph_unlock(periph);
620	cam_periph_release(periph);
621
622	return (0);
623}
624
625static int
626targallocinstance(struct ioc_alloc_unit *alloc_unit)
627{
628	struct ccb_pathinq cpi;
629	struct cam_path *path;
630	struct cam_periph *periph;
631	cam_status status;
632	int free_path_on_return;
633	int error;
634
635	free_path_on_return = 0;
636	status = xpt_create_path(&path, /*periph*/NULL,
637				 alloc_unit->path_id,
638				 alloc_unit->target_id,
639				 alloc_unit->lun_id);
640	if (status != CAM_REQ_CMP) {
641		printf("Couldn't Allocate Path %x\n", status);
642		goto fail;
643	}
644
645	free_path_on_return++;
646
647
648	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
649	cpi.ccb_h.func_code = XPT_PATH_INQ;
650	xpt_action((union ccb *)&cpi);
651	status = cpi.ccb_h.status;
652
653	if (status != CAM_REQ_CMP) {
654		printf("Couldn't CPI %x\n", status);
655		goto fail;
656	}
657
658	/* Can only alloc units on controllers that support target mode */
659	if ((cpi.target_sprt & PIT_PROCESSOR) == 0) {
660		printf("Controller does not support target mode%x\n", status);
661		status = CAM_PATH_INVALID;
662		goto fail;
663	}
664
665	/* Ensure that we don't already have an instance for this unit. */
666	if ((periph = cam_periph_find(path, "targ")) != NULL) {
667		status = CAM_LUN_ALRDY_ENA;
668		goto fail;
669	}
670
671	/*
672	 * Allocate a peripheral instance for
673	 * this target instance.
674	 */
675	status = cam_periph_alloc(targctor, NULL, targdtor, targstart,
676				  "targ", CAM_PERIPH_BIO, path, targasync,
677				  0, &cpi);
678
679fail:
680	switch (status) {
681	case CAM_REQ_CMP:
682	{
683		struct cam_periph *periph;
684
685		if ((periph = cam_periph_find(path, "targ")) == NULL)
686			panic("targallocinstance: Succeeded but no periph?");
687		error = 0;
688		alloc_unit->unit = periph->unit_number;
689		break;
690	}
691	case CAM_RESRC_UNAVAIL:
692		error = ENOMEM;
693		break;
694	case CAM_LUN_ALRDY_ENA:
695		error = EADDRINUSE;
696		break;
697	default:
698		printf("targallocinstance: Unexpected CAM status %x\n", status);
699		/* FALLTHROUGH */
700	case CAM_PATH_INVALID:
701		error = ENXIO;
702		break;
703	case CAM_PROVIDE_FAIL:
704		error = ENODEV;
705		break;
706	}
707
708	if (free_path_on_return != 0)
709		xpt_free_path(path);
710
711	return (error);
712}
713
714static int
715targfreeinstance(struct ioc_alloc_unit *alloc_unit)
716{
717	struct cam_path *path;
718	struct cam_periph *periph;
719	struct targ_softc *softc;
720	cam_status status;
721	int free_path_on_return;
722	int error;
723
724	periph = NULL;
725	free_path_on_return = 0;
726	status = xpt_create_path(&path, /*periph*/NULL,
727				 alloc_unit->path_id,
728				 alloc_unit->target_id,
729				 alloc_unit->lun_id);
730	free_path_on_return++;
731
732	if (status != CAM_REQ_CMP)
733		goto fail;
734
735	/* Find our instance. */
736	if ((periph = cam_periph_find(path, "targ")) == NULL) {
737		xpt_print_path(path);
738		printf("Invalid path specified for freeing target instance\n");
739		status = CAM_PATH_INVALID;
740		goto fail;
741	}
742
743        softc = (struct targ_softc *)periph->softc;
744
745        if ((softc->flags & TARG_FLAG_LUN_ENABLED) != 0) {
746		status = CAM_BUSY;
747		goto fail;
748	}
749
750fail:
751	if (free_path_on_return != 0)
752		xpt_free_path(path);
753
754	switch (status) {
755	case CAM_REQ_CMP:
756		if (periph != NULL)
757			cam_periph_invalidate(periph);
758		error = 0;
759		break;
760	case CAM_RESRC_UNAVAIL:
761		error = ENOMEM;
762		break;
763	case CAM_LUN_ALRDY_ENA:
764		error = EADDRINUSE;
765		break;
766	default:
767		printf("targfreeinstance: Unexpected CAM status %x\n", status);
768		/* FALLTHROUGH */
769	case CAM_PATH_INVALID:
770		error = ENODEV;
771		break;
772	}
773	return (error);
774}
775
776static int
777targioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
778{
779	struct cam_periph *periph;
780	struct targ_softc *softc;
781	u_int  unit;
782	int    error;
783
784	unit = minor(dev);
785	error = 0;
786	if (TARG_IS_CONTROL_DEV(unit)) {
787		switch (cmd) {
788		case TARGCTLIOALLOCUNIT:
789			error = targallocinstance((struct ioc_alloc_unit*)addr);
790			break;
791		case TARGCTLIOFREEUNIT:
792			error = targfreeinstance((struct ioc_alloc_unit*)addr);
793			break;
794		default:
795			error = EINVAL;
796			break;
797		}
798		return (error);
799	}
800
801	periph = cam_extend_get(targperiphs, unit);
802	if (periph == NULL)
803		return (ENXIO);
804	softc = (struct targ_softc *)periph->softc;
805	switch (cmd) {
806	case TARGIOCFETCHEXCEPTION:
807		*((targ_exception *)addr) = softc->exceptions;
808		break;
809	case TARGIOCCLEAREXCEPTION:
810	{
811		targ_exception clear_mask;
812
813		clear_mask = *((targ_exception *)addr);
814		if ((clear_mask & TARG_EXCEPT_UNKNOWN_ATIO) != 0) {
815			struct ccb_hdr *ccbh;
816
817			ccbh = TAILQ_FIRST(&softc->unknown_atio_queue);
818			if (ccbh != NULL) {
819				TAILQ_REMOVE(&softc->unknown_atio_queue,
820					     ccbh, periph_links.tqe);
821				/* Requeue the ATIO back to the controller */
822				xpt_action((union ccb *)ccbh);
823				ccbh = TAILQ_FIRST(&softc->unknown_atio_queue);
824			}
825			if (ccbh != NULL)
826				clear_mask &= ~TARG_EXCEPT_UNKNOWN_ATIO;
827		}
828		softc->exceptions &= ~clear_mask;
829		if (softc->exceptions == TARG_EXCEPT_NONE
830		 && softc->state == TARG_STATE_EXCEPTION) {
831			softc->state = TARG_STATE_NORMAL;
832			targrunqueue(periph, softc);
833		}
834		break;
835	}
836	case TARGIOCFETCHATIO:
837	{
838		struct ccb_hdr *ccbh;
839
840		ccbh = TAILQ_FIRST(&softc->unknown_atio_queue);
841		if (ccbh != NULL) {
842			bcopy(ccbh, addr, sizeof(struct ccb_accept_tio));
843		} else {
844			error = ENOENT;
845		}
846		break;
847	}
848	case TARGIOCCOMMAND:
849	{
850		union ccb *inccb;
851		union ccb *ccb;
852
853		/*
854		 * XXX JGibbs
855		 * This code is lifted directly from the pass-thru driver.
856		 * Perhaps this should be moved to a library????
857		 */
858		inccb = (union ccb *)addr;
859		ccb = cam_periph_getccb(periph, inccb->ccb_h.pinfo.priority);
860
861		error = targsendccb(periph, ccb, inccb);
862
863		xpt_release_ccb(ccb);
864
865		break;
866	}
867	case TARGIOCGETISTATE:
868	case TARGIOCSETISTATE:
869	{
870		struct ioc_initiator_state *ioc_istate;
871
872		ioc_istate = (struct ioc_initiator_state *)addr;
873		if (ioc_istate->initiator_id > MAX_INITIATORS) {
874			error = EINVAL;
875			break;
876		}
877		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
878			  ("GET/SETISTATE for %d\n", ioc_istate->initiator_id));
879		if (cmd == TARGIOCGETISTATE) {
880			bcopy(&softc->istate[ioc_istate->initiator_id],
881			      &ioc_istate->istate, sizeof(ioc_istate->istate));
882		} else {
883			bcopy(&ioc_istate->istate,
884			      &softc->istate[ioc_istate->initiator_id],
885			      sizeof(ioc_istate->istate));
886		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
887			  ("pending_ca now %x\n",
888			   softc->istate[ioc_istate->initiator_id].pending_ca));
889		}
890		break;
891	}
892	default:
893		error = ENOTTY;
894		break;
895	}
896	return (error);
897}
898
899/*
900 * XXX JGibbs lifted from pass-thru driver.
901 * Generally, "ccb" should be the CCB supplied by the kernel.  "inccb"
902 * should be the CCB that is copied in from the user.
903 */
904static int
905targsendccb(struct cam_periph *periph, union ccb *ccb, union ccb *inccb)
906{
907	struct targ_softc *softc;
908	struct cam_periph_map_info mapinfo;
909	int error, need_unmap;
910	int s;
911
912	softc = (struct targ_softc *)periph->softc;
913
914	need_unmap = 0;
915
916	/*
917	 * There are some fields in the CCB header that need to be
918	 * preserved, the rest we get from the user.
919	 */
920	xpt_merge_ccb(ccb, inccb);
921
922	/*
923	 * There's no way for the user to have a completion
924	 * function, so we put our own completion function in here.
925	 */
926	ccb->ccb_h.cbfcnp = targdone;
927
928	/*
929	 * We only attempt to map the user memory into kernel space
930	 * if they haven't passed in a physical memory pointer,
931	 * and if there is actually an I/O operation to perform.
932	 * Right now cam_periph_mapmem() only supports SCSI and device
933	 * match CCBs.  For the SCSI CCBs, we only pass the CCB in if
934	 * there's actually data to map.  cam_periph_mapmem() will do the
935	 * right thing, even if there isn't data to map, but since CCBs
936	 * without data are a reasonably common occurance (e.g. test unit
937	 * ready), it will save a few cycles if we check for it here.
938	 */
939	if (((ccb->ccb_h.flags & CAM_DATA_PHYS) == 0)
940	 && (((ccb->ccb_h.func_code == XPT_CONT_TARGET_IO)
941	    && ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE))
942	  || (ccb->ccb_h.func_code == XPT_DEV_MATCH))) {
943
944		bzero(&mapinfo, sizeof(mapinfo));
945
946		error = cam_periph_mapmem(ccb, &mapinfo);
947
948		/*
949		 * cam_periph_mapmem returned an error, we can't continue.
950		 * Return the error to the user.
951		 */
952		if (error)
953			return(error);
954
955		/*
956		 * We successfully mapped the memory in, so we need to
957		 * unmap it when the transaction is done.
958		 */
959		need_unmap = 1;
960	}
961
962	/*
963	 * Once queued on the pending CCB list, this CCB will be protected
964	 * by the error recovery handling used for 'buffer I/O' ccbs.  Since
965	 * we are in a process context here, however, the software interrupt
966	 * for this driver may deliver an event invalidating this CCB just
967	 * before we queue it.  Close this race condition by blocking
968	 * software interrupt delivery, checking for any pertinent queued
969	 * events, and only then queuing this CCB.
970	 */
971	s = splsoftcam();
972	if (softc->exceptions == 0) {
973		if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO)
974			TAILQ_INSERT_TAIL(&softc->pending_queue, &ccb->ccb_h,
975					  periph_links.tqe);
976
977		/*
978		 * If the user wants us to perform any error recovery,
979		 * then honor that request.  Otherwise, it's up to the
980		 * user to perform any error recovery.
981		 */
982		error = cam_periph_runccb(ccb,
983					  /* error handler */NULL,
984					  /* cam_flags */ 0,
985					  /* sense_flags */SF_RETRY_UA,
986					  &softc->device_stats);
987
988		if (ccb->ccb_h.func_code == XPT_CONT_TARGET_IO)
989			TAILQ_REMOVE(&softc->pending_queue, &ccb->ccb_h,
990				     periph_links.tqe);
991	} else {
992		ccb->ccb_h.status = CAM_UNACKED_EVENT;
993		error = 0;
994	}
995	splx(s);
996
997	if (need_unmap != 0)
998		cam_periph_unmapmem(ccb, &mapinfo);
999
1000	ccb->ccb_h.cbfcnp = NULL;
1001	ccb->ccb_h.periph_priv = inccb->ccb_h.periph_priv;
1002	bcopy(ccb, inccb, sizeof(union ccb));
1003
1004	return(error);
1005}
1006
1007
1008static int
1009targpoll(dev_t dev, int poll_events, struct proc *p)
1010{
1011	struct cam_periph *periph;
1012	struct targ_softc *softc;
1013	u_int  unit;
1014	int    revents;
1015	int    s;
1016
1017	unit = minor(dev);
1018
1019	/* ioctl is the only supported operation of the control device */
1020	if (TARG_IS_CONTROL_DEV(unit))
1021		return EINVAL;
1022
1023	periph = cam_extend_get(targperiphs, unit);
1024	if (periph == NULL)
1025		return (ENXIO);
1026	softc = (struct targ_softc *)periph->softc;
1027
1028	revents = 0;
1029	s = splcam();
1030	if ((poll_events & (POLLOUT | POLLWRNORM)) != 0) {
1031		if (TAILQ_FIRST(&softc->rcv_ccb_queue) != NULL
1032		 && bioq_first(&softc->rcv_bio_queue) == NULL)
1033			revents |= poll_events & (POLLOUT | POLLWRNORM);
1034	}
1035	if ((poll_events & (POLLIN | POLLRDNORM)) != 0) {
1036		if (TAILQ_FIRST(&softc->snd_ccb_queue) != NULL
1037		 && bioq_first(&softc->snd_bio_queue) == NULL)
1038			revents |= poll_events & (POLLIN | POLLRDNORM);
1039	}
1040
1041	if (softc->state != TARG_STATE_NORMAL)
1042		revents |= POLLERR;
1043
1044	if (revents == 0) {
1045		if (poll_events & (POLLOUT | POLLWRNORM))
1046			selrecord(p, &softc->rcv_select);
1047		if (poll_events & (POLLIN | POLLRDNORM))
1048			selrecord(p, &softc->snd_select);
1049	}
1050	splx(s);
1051	return (revents);
1052}
1053
1054static int
1055targread(dev_t dev, struct uio *uio, int ioflag)
1056{
1057	u_int  unit;
1058
1059	unit = minor(dev);
1060	/* ioctl is the only supported operation of the control device */
1061	if (TARG_IS_CONTROL_DEV(unit))
1062		return EINVAL;
1063
1064	if (uio->uio_iovcnt == 0
1065	 || uio->uio_iov->iov_len == 0) {
1066		/* EOF */
1067		struct cam_periph *periph;
1068		struct targ_softc *softc;
1069		int    s;
1070
1071		s = splcam();
1072		periph = cam_extend_get(targperiphs, unit);
1073		if (periph == NULL)
1074			return (ENXIO);
1075		softc = (struct targ_softc *)periph->softc;
1076		softc->flags |= TARG_FLAG_SEND_EOF;
1077		splx(s);
1078		targrunqueue(periph, softc);
1079		return (0);
1080	}
1081	return(physread(dev, uio, ioflag));
1082}
1083
1084static int
1085targwrite(dev_t dev, struct uio *uio, int ioflag)
1086{
1087	u_int  unit;
1088
1089	unit = minor(dev);
1090	/* ioctl is the only supported operation of the control device */
1091	if (TARG_IS_CONTROL_DEV(unit))
1092		return EINVAL;
1093
1094	if (uio->uio_iovcnt == 0
1095	 || uio->uio_iov->iov_len == 0) {
1096		/* EOF */
1097		struct cam_periph *periph;
1098		struct targ_softc *softc;
1099		int    s;
1100
1101		s = splcam();
1102		periph = cam_extend_get(targperiphs, unit);
1103		if (periph == NULL)
1104			return (ENXIO);
1105		softc = (struct targ_softc *)periph->softc;
1106		softc->flags |= TARG_FLAG_RECEIVE_EOF;
1107		splx(s);
1108		targrunqueue(periph, softc);
1109		return (0);
1110	}
1111	return(physwrite(dev, uio, ioflag));
1112}
1113
1114/*
1115 * Actually translate the requested transfer into one the physical driver
1116 * can understand.  The transfer is described by a buf and will include
1117 * only one physical transfer.
1118 */
1119static void
1120targstrategy(struct bio *bp)
1121{
1122	struct cam_periph *periph;
1123	struct targ_softc *softc;
1124	u_int  unit;
1125	int    s;
1126
1127	unit = minor(bp->bio_dev);
1128
1129	/* ioctl is the only supported operation of the control device */
1130	if (TARG_IS_CONTROL_DEV(unit)) {
1131		bp->bio_error = EINVAL;
1132		goto bad;
1133	}
1134
1135	periph = cam_extend_get(targperiphs, unit);
1136	if (periph == NULL) {
1137		bp->bio_error = ENXIO;
1138		goto bad;
1139	}
1140	softc = (struct targ_softc *)periph->softc;
1141
1142	/*
1143	 * Mask interrupts so that the device cannot be invalidated until
1144	 * after we are in the queue.  Otherwise, we might not properly
1145	 * clean up one of the buffers.
1146	 */
1147	s = splbio();
1148
1149	/*
1150	 * If there is an exception pending, error out
1151	 */
1152	if (softc->state != TARG_STATE_NORMAL) {
1153		splx(s);
1154		if (softc->state == TARG_STATE_EXCEPTION
1155		 && (softc->exceptions & TARG_EXCEPT_DEVICE_INVALID) == 0)
1156			bp->bio_error = EBUSY;
1157		else
1158			bp->bio_error = ENXIO;
1159		goto bad;
1160	}
1161
1162	/*
1163	 * Place it in the queue of buffers available for either
1164	 * SEND or RECEIVE commands.
1165	 *
1166	 */
1167	bp->bio_resid = bp->bio_bcount;
1168	if (bp->bio_cmd == BIO_READ) {
1169		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1170			  ("Queued a SEND buffer\n"));
1171		bioq_insert_tail(&softc->snd_bio_queue, bp);
1172	} else {
1173		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1174			  ("Queued a RECEIVE buffer\n"));
1175		bioq_insert_tail(&softc->rcv_bio_queue, bp);
1176	}
1177
1178	splx(s);
1179
1180	/*
1181	 * Attempt to use the new buffer to service any pending
1182	 * target commands.
1183	 */
1184	targrunqueue(periph, softc);
1185
1186	return;
1187bad:
1188	bp->bio_flags |= BIO_ERROR;
1189
1190	/*
1191	 * Correctly set the buf to indicate a completed xfer
1192	 */
1193	bp->bio_resid = bp->bio_bcount;
1194	biodone(bp);
1195}
1196
1197static void
1198targrunqueue(struct cam_periph *periph, struct targ_softc *softc)
1199{
1200	struct  ccb_queue *pending_queue;
1201	struct	ccb_accept_tio *atio;
1202	struct	bio_queue_head *bioq;
1203	struct	bio *bp;
1204	struct	targ_cmd_desc *desc;
1205	struct	ccb_hdr *ccbh;
1206	int	s;
1207
1208	s = splbio();
1209	pending_queue = NULL;
1210	bioq = NULL;
1211	ccbh = NULL;
1212	/* Only run one request at a time to maintain data ordering. */
1213	if (softc->state != TARG_STATE_NORMAL
1214	 || TAILQ_FIRST(&softc->work_queue) != NULL
1215	 || TAILQ_FIRST(&softc->pending_queue) != NULL) {
1216		splx(s);
1217		return;
1218	}
1219
1220	if (((bp = bioq_first(&softc->snd_bio_queue)) != NULL
1221	  || (softc->flags & TARG_FLAG_SEND_EOF) != 0)
1222	 && (ccbh = TAILQ_FIRST(&softc->snd_ccb_queue)) != NULL) {
1223
1224		if (bp == NULL)
1225			softc->flags &= ~TARG_FLAG_SEND_EOF;
1226		else {
1227			CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1228				  ("De-Queued a SEND buffer %ld\n",
1229				   bp->bio_bcount));
1230		}
1231		bioq = &softc->snd_bio_queue;
1232		pending_queue = &softc->snd_ccb_queue;
1233	} else if (((bp = bioq_first(&softc->rcv_bio_queue)) != NULL
1234	  	 || (softc->flags & TARG_FLAG_RECEIVE_EOF) != 0)
1235		&& (ccbh = TAILQ_FIRST(&softc->rcv_ccb_queue)) != NULL) {
1236
1237		if (bp == NULL)
1238			softc->flags &= ~TARG_FLAG_RECEIVE_EOF;
1239		else {
1240			CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1241				  ("De-Queued a RECEIVE buffer %ld\n",
1242				   bp->bio_bcount));
1243		}
1244		bioq = &softc->rcv_bio_queue;
1245		pending_queue = &softc->rcv_ccb_queue;
1246	}
1247
1248	if (pending_queue != NULL) {
1249		/* Process a request */
1250		atio = (struct ccb_accept_tio *)ccbh;
1251		TAILQ_REMOVE(pending_queue, ccbh, periph_links.tqe);
1252		desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr;
1253		desc->bp = bp;
1254		if (bp == NULL) {
1255			/* EOF */
1256			desc->data = NULL;
1257			desc->data_increment = 0;
1258			desc->data_resid = 0;
1259			atio->ccb_h.flags &= ~CAM_DIR_MASK;
1260			atio->ccb_h.flags |= CAM_DIR_NONE;
1261		} else {
1262			bioq_remove(bioq, bp);
1263			desc->data = &bp->bio_data[bp->bio_bcount - bp->bio_resid];
1264			desc->data_increment =
1265			    MIN(desc->data_resid, bp->bio_resid);
1266			desc->data_increment =
1267			    MIN(desc->data_increment, 32);
1268		}
1269		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1270			  ("Buffer command: data %p: datacnt %d\n",
1271			   (intptr_t)desc->data, desc->data_increment));
1272		TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h,
1273				  periph_links.tqe);
1274	}
1275	if (TAILQ_FIRST(&softc->work_queue) != NULL) {
1276		splx(s);
1277		xpt_schedule(periph, /*XXX priority*/1);
1278	} else
1279		splx(s);
1280}
1281
1282static void
1283targstart(struct cam_periph *periph, union ccb *start_ccb)
1284{
1285	struct targ_softc *softc;
1286	struct ccb_hdr *ccbh;
1287	struct ccb_accept_tio *atio;
1288	struct targ_cmd_desc *desc;
1289	struct ccb_scsiio *csio;
1290	targ_ccb_flags flags;
1291	int    s;
1292
1293	softc = (struct targ_softc *)periph->softc;
1294
1295	s = splbio();
1296	ccbh = TAILQ_FIRST(&softc->work_queue);
1297	if (periph->immediate_priority <= periph->pinfo.priority) {
1298		start_ccb->ccb_h.ccb_flags = TARG_CCB_WAITING;
1299		SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1300				  periph_links.sle);
1301		periph->immediate_priority = CAM_PRIORITY_NONE;
1302		splx(s);
1303		wakeup(&periph->ccb_list);
1304	} else if (ccbh == NULL) {
1305		splx(s);
1306		xpt_release_ccb(start_ccb);
1307	} else {
1308		TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe);
1309		splx(s);
1310		atio = (struct ccb_accept_tio*)ccbh;
1311		desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr;
1312
1313		/* Is this a tagged request? */
1314		flags = atio->ccb_h.flags & (CAM_TAG_ACTION_VALID|CAM_DIR_MASK);
1315
1316		/*
1317		 * If we are done with the transaction, tell the
1318		 * controller to send status and perform a CMD_CMPLT.
1319		 */
1320		if (desc->data_resid == desc->data_increment)
1321			flags |= CAM_SEND_STATUS;
1322
1323		csio = &start_ccb->csio;
1324		cam_fill_ctio(csio,
1325			      /*retries*/2,
1326			      targdone,
1327			      flags,
1328			      /*tag_action*/MSG_SIMPLE_Q_TAG,
1329			      atio->tag_id,
1330			      atio->init_id,
1331			      desc->status,
1332			      /*data_ptr*/desc->data_increment == 0
1333					  ? NULL : desc->data,
1334			      /*dxfer_len*/desc->data_increment,
1335			      /*timeout*/desc->timeout);
1336
1337		if ((flags & CAM_SEND_STATUS) != 0
1338		 && (desc->status == SCSI_STATUS_CHECK_COND
1339		  || desc->status == SCSI_STATUS_CMD_TERMINATED)) {
1340			struct initiator_state *istate;
1341
1342			istate = &softc->istate[atio->init_id];
1343			csio->sense_len = istate->sense_data.extra_len
1344					+ offsetof(struct scsi_sense_data,
1345						   extra_len);
1346			bcopy(&istate->sense_data, &csio->sense_data,
1347			      csio->sense_len);
1348			csio->ccb_h.flags |= CAM_SEND_SENSE;
1349		} else {
1350			csio->sense_len = 0;
1351		}
1352
1353		start_ccb->ccb_h.ccb_flags = TARG_CCB_NONE;
1354		start_ccb->ccb_h.ccb_atio = atio;
1355		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1356			  ("Sending a CTIO\n"));
1357		TAILQ_INSERT_TAIL(&softc->pending_queue, &csio->ccb_h,
1358				  periph_links.tqe);
1359		xpt_action(start_ccb);
1360		s = splbio();
1361		ccbh = TAILQ_FIRST(&softc->work_queue);
1362		splx(s);
1363	}
1364	if (ccbh != NULL)
1365		targrunqueue(periph, softc);
1366}
1367
1368static void
1369targdone(struct cam_periph *periph, union ccb *done_ccb)
1370{
1371	struct targ_softc *softc;
1372
1373	softc = (struct targ_softc *)periph->softc;
1374
1375	if (done_ccb->ccb_h.ccb_flags == TARG_CCB_WAITING) {
1376		/* Caller will release the CCB */
1377		wakeup(&done_ccb->ccb_h.cbfcnp);
1378		return;
1379	}
1380
1381	switch (done_ccb->ccb_h.func_code) {
1382	case XPT_ACCEPT_TARGET_IO:
1383	{
1384		struct ccb_accept_tio *atio;
1385		struct targ_cmd_desc *descr;
1386		struct initiator_state *istate;
1387		u_int8_t *cdb;
1388
1389		atio = &done_ccb->atio;
1390		descr = (struct targ_cmd_desc*)atio->ccb_h.ccb_descr;
1391		istate = &softc->istate[atio->init_id];
1392		cdb = atio->cdb_io.cdb_bytes;
1393		if (softc->state == TARG_STATE_TEARDOWN
1394		 || atio->ccb_h.status == CAM_REQ_ABORTED) {
1395			freedescr(descr);
1396			free(done_ccb, M_DEVBUF);
1397			return;
1398		}
1399
1400		if (atio->sense_len != 0) {
1401
1402			/*
1403			 * We had an error in the reception of
1404			 * this command.  Immediately issue a CA.
1405			 */
1406			atio->ccb_h.flags &= ~CAM_DIR_MASK;
1407			atio->ccb_h.flags |= CAM_DIR_NONE;
1408			descr->data_resid = 0;
1409			descr->data_increment = 0;
1410			descr->timeout = 5 * 1000;
1411			descr->status = SCSI_STATUS_CHECK_COND;
1412			copy_sense(softc, istate, (u_int8_t *)&atio->sense_data,
1413				   atio->sense_len);
1414			set_ca_condition(periph, atio->init_id, CA_CMD_SENSE);
1415		} else if (istate->pending_ca == 0
1416			&& istate->pending_ua != 0
1417			&& cdb[0] != INQUIRY) {
1418
1419			/* Pending UA, tell initiator */
1420			/* Direction is always relative to the initator */
1421			atio->ccb_h.flags &= ~CAM_DIR_MASK;
1422			atio->ccb_h.flags |= CAM_DIR_NONE;
1423			descr->data_resid = 0;
1424			descr->data_increment = 0;
1425			descr->timeout = 5 * 1000;
1426			descr->status = SCSI_STATUS_CHECK_COND;
1427			fill_sense(softc, atio->init_id,
1428				   SSD_CURRENT_ERROR, SSD_KEY_UNIT_ATTENTION,
1429				   0x29,
1430				   istate->pending_ua == UA_POWER_ON ? 1 : 2);
1431			set_ca_condition(periph, atio->init_id, CA_UNIT_ATTN);
1432		} else {
1433			/*
1434			 * Save the current CA and UA status so
1435			 * they can be used by this command.
1436			 */
1437			ua_types pending_ua;
1438			ca_types pending_ca;
1439
1440			pending_ua = istate->pending_ua;
1441			pending_ca = istate->pending_ca;
1442
1443			/*
1444			 * As per the SCSI2 spec, any command that occurs
1445			 * after a CA is reported, clears the CA.  We must
1446			 * also clear the UA condition, if any, that caused
1447			 * the CA to occur assuming the UA is not for a
1448			 * persistant condition.
1449			 */
1450			istate->pending_ca = CA_NONE;
1451			if (pending_ca == CA_UNIT_ATTN)
1452				istate->pending_ua = UA_NONE;
1453
1454			/*
1455			 * Determine the type of incoming command and
1456			 * setup our buffer for a response.
1457			 */
1458			switch (cdb[0]) {
1459			case INQUIRY:
1460			{
1461				struct scsi_inquiry *inq;
1462				struct scsi_sense_data *sense;
1463
1464				inq = (struct scsi_inquiry *)cdb;
1465				sense = &istate->sense_data;
1466				descr->status = SCSI_STATUS_OK;
1467				CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1468					  ("Saw an inquiry!\n"));
1469				/*
1470				 * Validate the command.  We don't
1471				 * support any VPD pages, so complain
1472				 * if EVPD is set.
1473				 */
1474				if ((inq->byte2 & SI_EVPD) != 0
1475				 || inq->page_code != 0) {
1476					atio->ccb_h.flags &= ~CAM_DIR_MASK;
1477					atio->ccb_h.flags |= CAM_DIR_NONE;
1478					descr->data_resid = 0;
1479					descr->data_increment = 0;
1480					descr->timeout = 5 * 1000;
1481					descr->status = SCSI_STATUS_CHECK_COND;
1482					fill_sense(softc, atio->init_id,
1483						   SSD_CURRENT_ERROR,
1484						   SSD_KEY_ILLEGAL_REQUEST,
1485						   /*asc*/0x24, /*ascq*/0x00);
1486					sense->extra_len =
1487						offsetof(struct scsi_sense_data,
1488							 extra_bytes)
1489					      - offsetof(struct scsi_sense_data,
1490							 extra_len);
1491					set_ca_condition(periph, atio->init_id,
1492							 CA_CMD_SENSE);
1493				}
1494
1495				if ((inq->byte2 & SI_EVPD) != 0) {
1496					sense->sense_key_spec[0] =
1497					    SSD_SCS_VALID|SSD_FIELDPTR_CMD
1498					   |SSD_BITPTR_VALID| /*bit value*/1;
1499					sense->sense_key_spec[1] = 0;
1500					sense->sense_key_spec[2] =
1501					    offsetof(struct scsi_inquiry,
1502						     byte2);
1503				} else if (inq->page_code != 0) {
1504					sense->sense_key_spec[0] =
1505					    SSD_SCS_VALID|SSD_FIELDPTR_CMD;
1506					sense->sense_key_spec[1] = 0;
1507					sense->sense_key_spec[2] =
1508					    offsetof(struct scsi_inquiry,
1509						     page_code);
1510				}
1511				if (descr->status == SCSI_STATUS_CHECK_COND)
1512					break;
1513
1514				/*
1515				 * Direction is always relative
1516				 * to the initator.
1517				 */
1518				atio->ccb_h.flags &= ~CAM_DIR_MASK;
1519				atio->ccb_h.flags |= CAM_DIR_IN;
1520				descr->data = softc->inq_data;
1521				descr->data_resid = MIN(softc->inq_data_len,
1522						       inq->length);
1523				descr->data_increment = descr->data_resid;
1524				descr->timeout = 5 * 1000;
1525				break;
1526			}
1527			case TEST_UNIT_READY:
1528				atio->ccb_h.flags &= ~CAM_DIR_MASK;
1529				atio->ccb_h.flags |= CAM_DIR_NONE;
1530				descr->data_resid = 0;
1531				descr->data_increment = 0;
1532				descr->timeout = 5 * 1000;
1533				descr->status = SCSI_STATUS_OK;
1534				break;
1535			case REQUEST_SENSE:
1536			{
1537				struct scsi_request_sense *rsense;
1538				struct scsi_sense_data *sense;
1539
1540				rsense = (struct scsi_request_sense *)cdb;
1541				sense = &istate->sense_data;
1542				if (pending_ca == 0) {
1543					fill_sense(softc, atio->init_id,
1544						   SSD_CURRENT_ERROR,
1545						   SSD_KEY_NO_SENSE, 0x00,
1546						   0x00);
1547					CAM_DEBUG(periph->path,
1548						  CAM_DEBUG_PERIPH,
1549						  ("No pending CA!\n"));
1550				}
1551				/*
1552				 * Direction is always relative
1553				 * to the initator.
1554				 */
1555				atio->ccb_h.flags &= ~CAM_DIR_MASK;
1556				atio->ccb_h.flags |= CAM_DIR_IN;
1557				descr->data = sense;
1558				descr->data_resid =
1559			 		offsetof(struct scsi_sense_data,
1560						 extra_len)
1561				      + sense->extra_len;
1562				descr->data_resid = MIN(descr->data_resid,
1563						       rsense->length);
1564				descr->data_increment = descr->data_resid;
1565				descr->timeout = 5 * 1000;
1566				descr->status = SCSI_STATUS_OK;
1567				break;
1568			}
1569			case RECEIVE:
1570			case SEND:
1571			{
1572				struct scsi_send_receive *sr;
1573
1574				sr = (struct scsi_send_receive *)cdb;
1575
1576				/*
1577				 * Direction is always relative
1578				 * to the initator.
1579				 */
1580				atio->ccb_h.flags &= ~CAM_DIR_MASK;
1581				descr->data_resid = scsi_3btoul(sr->xfer_len);
1582				descr->timeout = 5 * 1000;
1583				descr->status = SCSI_STATUS_OK;
1584				if (cdb[0] == SEND) {
1585					atio->ccb_h.flags |= CAM_DIR_OUT;
1586					CAM_DEBUG(periph->path,
1587						  CAM_DEBUG_PERIPH,
1588						  ("Saw a SEND!\n"));
1589					atio->ccb_h.flags |= CAM_DIR_OUT;
1590					TAILQ_INSERT_TAIL(&softc->snd_ccb_queue,
1591							  &atio->ccb_h,
1592							  periph_links.tqe);
1593					selwakeup(&softc->snd_select);
1594				} else {
1595					atio->ccb_h.flags |= CAM_DIR_IN;
1596					CAM_DEBUG(periph->path,
1597						  CAM_DEBUG_PERIPH,
1598						  ("Saw a RECEIVE!\n"));
1599					TAILQ_INSERT_TAIL(&softc->rcv_ccb_queue,
1600							  &atio->ccb_h,
1601							  periph_links.tqe);
1602					selwakeup(&softc->rcv_select);
1603				}
1604				/*
1605				 * Attempt to satisfy this request with
1606				 * a user buffer.
1607				 */
1608				targrunqueue(periph, softc);
1609				return;
1610			}
1611			default:
1612				/*
1613				 * Queue for consumption by our userland
1614				 * counterpart and  transition to the exception
1615				 * state.
1616				 */
1617				TAILQ_INSERT_TAIL(&softc->unknown_atio_queue,
1618						  &atio->ccb_h,
1619						  periph_links.tqe);
1620				softc->exceptions |= TARG_EXCEPT_UNKNOWN_ATIO;
1621				targfireexception(periph, softc);
1622				return;
1623			}
1624		}
1625
1626		/* Queue us up to receive a Continue Target I/O ccb. */
1627		TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h,
1628				  periph_links.tqe);
1629		xpt_schedule(periph, /*priority*/1);
1630		break;
1631	}
1632	case XPT_CONT_TARGET_IO:
1633	{
1634		struct ccb_scsiio *csio;
1635		struct ccb_accept_tio *atio;
1636		struct targ_cmd_desc *desc;
1637		struct bio *bp;
1638		int    error;
1639
1640		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1641			  ("Received completed CTIO\n"));
1642		csio = &done_ccb->csio;
1643		atio = (struct ccb_accept_tio*)done_ccb->ccb_h.ccb_atio;
1644		desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr;
1645
1646		TAILQ_REMOVE(&softc->pending_queue, &done_ccb->ccb_h,
1647			     periph_links.tqe);
1648
1649		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1650			printf("CCB with error %x\n", done_ccb->ccb_h.status);
1651			error = targerror(done_ccb, 0, 0);
1652			if (error == ERESTART)
1653				break;
1654			/*
1655			 * Right now we don't need to do anything
1656			 * prior to unfreezing the queue...
1657			 */
1658			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1659				printf("Releasing Queue\n");
1660				cam_release_devq(done_ccb->ccb_h.path,
1661						 /*relsim_flags*/0,
1662						 /*reduction*/0,
1663						 /*timeout*/0,
1664						 /*getcount_only*/0);
1665			}
1666		} else
1667			error = 0;
1668
1669		/*
1670		 * If we shipped back sense data when completing
1671		 * this command, clear the pending CA for it.
1672		 */
1673		if (done_ccb->ccb_h.status & CAM_SENT_SENSE) {
1674			struct initiator_state *istate;
1675
1676			istate = &softc->istate[csio->init_id];
1677			if (istate->pending_ca == CA_UNIT_ATTN)
1678				istate->pending_ua = UA_NONE;
1679			istate->pending_ca = CA_NONE;
1680			softc->istate[csio->init_id].pending_ca = CA_NONE;
1681			done_ccb->ccb_h.status &= ~CAM_SENT_SENSE;
1682		}
1683		done_ccb->ccb_h.flags &= ~CAM_SEND_SENSE;
1684
1685		desc->data_increment -= csio->resid;
1686		desc->data_resid -= desc->data_increment;
1687		if ((bp = desc->bp) != NULL) {
1688
1689			bp->bio_resid -= desc->data_increment;
1690			bp->bio_error = error;
1691
1692			CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1693				  ("Buffer I/O Completed - Resid %ld:%d\n",
1694				   bp->bio_resid, desc->data_resid));
1695			/*
1696			 * Send the buffer back to the client if
1697			 * either the command has completed or all
1698			 * buffer space has been consumed.
1699			 */
1700			if (desc->data_resid == 0
1701			 || bp->bio_resid == 0
1702			 || error != 0) {
1703				if (bp->bio_resid != 0)
1704					/* Short transfer */
1705					bp->bio_flags |= BIO_ERROR;
1706
1707				CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1708					  ("Completing a buffer\n"));
1709				biodone(bp);
1710				desc->bp = NULL;
1711			}
1712		}
1713
1714		xpt_release_ccb(done_ccb);
1715		if (softc->state != TARG_STATE_TEARDOWN) {
1716
1717			if (desc->data_resid == 0) {
1718				/*
1719				 * Send the original accept TIO back to the
1720				 * controller to handle more work.
1721				 */
1722				CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
1723					  ("Returning ATIO to target\n"));
1724				xpt_action((union ccb *)atio);
1725				break;
1726			}
1727
1728			/* Queue us up for another buffer */
1729			if (atio->cdb_io.cdb_bytes[0] == SEND) {
1730				if (desc->bp != NULL)
1731					TAILQ_INSERT_HEAD(
1732						&softc->snd_bio_queue.queue,
1733						bp, bio_queue);
1734				TAILQ_INSERT_HEAD(&softc->snd_ccb_queue,
1735						  &atio->ccb_h,
1736						  periph_links.tqe);
1737			} else {
1738				if (desc->bp != NULL)
1739					TAILQ_INSERT_HEAD(
1740						&softc->rcv_bio_queue.queue,
1741						bp, bio_queue);
1742				TAILQ_INSERT_HEAD(&softc->rcv_ccb_queue,
1743						  &atio->ccb_h,
1744						  periph_links.tqe);
1745			}
1746			desc->bp = NULL;
1747			targrunqueue(periph, softc);
1748		} else {
1749			if (desc->bp != NULL) {
1750				bp->bio_flags |= BIO_ERROR;
1751				bp->bio_error = ENXIO;
1752				biodone(bp);
1753			}
1754			freedescr(desc);
1755			free(atio, M_DEVBUF);
1756		}
1757		break;
1758	}
1759	case XPT_IMMED_NOTIFY:
1760	{
1761		int frozen;
1762
1763		frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
1764		if (softc->state == TARG_STATE_TEARDOWN) {
1765			SLIST_REMOVE(&softc->immed_notify_slist,
1766				     &done_ccb->ccb_h, ccb_hdr,
1767				     periph_links.sle);
1768			free(done_ccb, M_DEVBUF);
1769		} else if (done_ccb->ccb_h.status == CAM_REQ_ABORTED) {
1770			free(done_ccb, M_DEVBUF);
1771		} else {
1772			printf("Saw event %x:%x\n", done_ccb->ccb_h.status,
1773			       done_ccb->cin.message_args[0]);
1774			/* Process error condition. */
1775			targinoterror(periph, softc, &done_ccb->cin);
1776
1777			/* Requeue for another immediate event */
1778			xpt_action(done_ccb);
1779		}
1780		if (frozen != 0)
1781			cam_release_devq(periph->path,
1782					 /*relsim_flags*/0,
1783					 /*opening reduction*/0,
1784					 /*timeout*/0,
1785					 /*getcount_only*/0);
1786		break;
1787	}
1788	default:
1789		panic("targdone: Impossible xpt opcode %x encountered.",
1790		      done_ccb->ccb_h.func_code);
1791		/* NOTREACHED */
1792		break;
1793	}
1794}
1795
1796/*
1797 * Transition to the exception state and notify our symbiotic
1798 * userland process of the change.
1799 */
1800static void
1801targfireexception(struct cam_periph *periph, struct targ_softc *softc)
1802{
1803	/*
1804	 * return all pending buffers with short read/write status so our
1805	 * process unblocks, and do a selwakeup on any process queued
1806	 * waiting for reads or writes.  When the selwakeup is performed,
1807	 * the waking process will wakeup, call our poll routine again,
1808	 * and pick up the exception.
1809	 */
1810	struct bio *bp;
1811
1812	if (softc->state != TARG_STATE_NORMAL)
1813		/* Already either tearing down or in exception state */
1814		return;
1815
1816	softc->state = TARG_STATE_EXCEPTION;
1817
1818	while ((bp = bioq_first(&softc->snd_bio_queue)) != NULL) {
1819		bioq_remove(&softc->snd_bio_queue, bp);
1820		bp->bio_flags |= BIO_ERROR;
1821		biodone(bp);
1822	}
1823
1824	while ((bp = bioq_first(&softc->rcv_bio_queue)) != NULL) {
1825		bioq_remove(&softc->snd_bio_queue, bp);
1826		bp->bio_flags |= BIO_ERROR;
1827		biodone(bp);
1828	}
1829
1830	selwakeup(&softc->snd_select);
1831	selwakeup(&softc->rcv_select);
1832}
1833
1834static void
1835targinoterror(struct cam_periph *periph, struct targ_softc *softc,
1836	      struct ccb_immed_notify *inot)
1837{
1838	cam_status status;
1839	int sense;
1840
1841	status = inot->ccb_h.status;
1842	sense = (status & CAM_AUTOSNS_VALID) != 0;
1843	status &= CAM_STATUS_MASK;
1844	switch (status) {
1845	case CAM_SCSI_BUS_RESET:
1846		set_unit_attention_cond(periph, /*init_id*/CAM_TARGET_WILDCARD,
1847					UA_BUS_RESET);
1848		abort_pending_transactions(periph,
1849					   /*init_id*/CAM_TARGET_WILDCARD,
1850					   TARG_TAG_WILDCARD, EINTR,
1851					   /*to_held_queue*/FALSE);
1852		softc->exceptions |= TARG_EXCEPT_BUS_RESET_SEEN;
1853		targfireexception(periph, softc);
1854		break;
1855	case CAM_BDR_SENT:
1856		set_unit_attention_cond(periph, /*init_id*/CAM_TARGET_WILDCARD,
1857					UA_BDR);
1858		abort_pending_transactions(periph, CAM_TARGET_WILDCARD,
1859					   TARG_TAG_WILDCARD, EINTR,
1860					   /*to_held_queue*/FALSE);
1861		softc->exceptions |= TARG_EXCEPT_BDR_RECEIVED;
1862		targfireexception(periph, softc);
1863		break;
1864	case CAM_MESSAGE_RECV:
1865		switch (inot->message_args[0]) {
1866		case MSG_INITIATOR_DET_ERR:
1867			break;
1868		case MSG_ABORT:
1869			break;
1870		case MSG_BUS_DEV_RESET:
1871			break;
1872		case MSG_ABORT_TAG:
1873			break;
1874		case MSG_CLEAR_QUEUE:
1875			break;
1876		case MSG_TERM_IO_PROC:
1877			break;
1878		default:
1879			break;
1880		}
1881		break;
1882	default:
1883		break;
1884	}
1885}
1886
1887static int
1888targerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
1889{
1890	struct cam_periph *periph;
1891	struct targ_softc *softc;
1892	struct ccb_scsiio *csio;
1893	struct initiator_state *istate;
1894	cam_status status;
1895	int frozen;
1896	int sense;
1897	int error;
1898	int on_held_queue;
1899
1900	periph = xpt_path_periph(ccb->ccb_h.path);
1901	softc = (struct targ_softc *)periph->softc;
1902	status = ccb->ccb_h.status;
1903	sense = (status & CAM_AUTOSNS_VALID) != 0;
1904	frozen = (status & CAM_DEV_QFRZN) != 0;
1905	status &= CAM_STATUS_MASK;
1906	on_held_queue = FALSE;
1907	csio = &ccb->csio;
1908	istate = &softc->istate[csio->init_id];
1909	switch (status) {
1910	case CAM_REQ_ABORTED:
1911		if ((ccb->ccb_h.ccb_flags & TARG_CCB_ABORT_TO_HELDQ) != 0) {
1912
1913			/*
1914			 * Place this CCB into the initiators
1915			 * 'held' queue until the pending CA is cleared.
1916			 * If there is no CA pending, reissue immediately.
1917			 */
1918			if (istate->pending_ca == 0) {
1919				ccb->ccb_h.ccb_flags = TARG_CCB_NONE;
1920				xpt_action(ccb);
1921			} else {
1922				ccb->ccb_h.ccb_flags = TARG_CCB_HELDQ;
1923				TAILQ_INSERT_TAIL(&softc->pending_queue,
1924						  &ccb->ccb_h,
1925						  periph_links.tqe);
1926			}
1927			/* The command will be retried at a later time. */
1928			on_held_queue = TRUE;
1929			error = ERESTART;
1930			break;
1931		}
1932		/* FALLTHROUGH */
1933	case CAM_SCSI_BUS_RESET:
1934	case CAM_BDR_SENT:
1935	case CAM_REQ_TERMIO:
1936	case CAM_CMD_TIMEOUT:
1937		/* Assume we did not send any data */
1938		csio->resid = csio->dxfer_len;
1939		error = EIO;
1940		break;
1941	case CAM_SEL_TIMEOUT:
1942		if (ccb->ccb_h.retry_count > 0) {
1943			ccb->ccb_h.retry_count--;
1944			error = ERESTART;
1945		} else {
1946			/* "Select or reselect failure" */
1947			csio->resid = csio->dxfer_len;
1948			fill_sense(softc, csio->init_id, SSD_CURRENT_ERROR,
1949				   SSD_KEY_HARDWARE_ERROR, 0x45, 0x00);
1950			set_ca_condition(periph, csio->init_id, CA_CMD_SENSE);
1951			error = EIO;
1952		}
1953		break;
1954	case CAM_UNCOR_PARITY:
1955		/* "SCSI parity error" */
1956		fill_sense(softc, csio->init_id, SSD_CURRENT_ERROR,
1957			   SSD_KEY_HARDWARE_ERROR, 0x47, 0x00);
1958		set_ca_condition(periph, csio->init_id,
1959					       CA_CMD_SENSE);
1960		csio->resid = csio->dxfer_len;
1961		error = EIO;
1962		break;
1963	case CAM_NO_HBA:
1964		csio->resid = csio->dxfer_len;
1965		error = ENXIO;
1966		break;
1967	case CAM_SEQUENCE_FAIL:
1968		if (sense != 0) {
1969			copy_sense(softc, istate, (u_int8_t *)&csio->sense_data,
1970				   csio->sense_len);
1971			set_ca_condition(periph,
1972						       csio->init_id,
1973						       CA_CMD_SENSE);
1974		}
1975		csio->resid = csio->dxfer_len;
1976		error = EIO;
1977		break;
1978	case CAM_IDE:
1979		/* "Initiator detected error message received" */
1980		fill_sense(softc, csio->init_id, SSD_CURRENT_ERROR,
1981			   SSD_KEY_HARDWARE_ERROR, 0x48, 0x00);
1982		set_ca_condition(periph, csio->init_id,
1983					       CA_CMD_SENSE);
1984		csio->resid = csio->dxfer_len;
1985		error = EIO;
1986		break;
1987	case CAM_REQUEUE_REQ:
1988		printf("Requeue Request!\n");
1989		error = ERESTART;
1990		break;
1991	default:
1992		csio->resid = csio->dxfer_len;
1993		error = EIO;
1994		panic("targerror: Unexpected status %x encounterd", status);
1995		/* NOTREACHED */
1996	}
1997
1998	if (error == ERESTART || error == 0) {
1999		/* Clear the QFRZN flag as we will release the queue */
2000		if (frozen != 0)
2001			ccb->ccb_h.status &= ~CAM_DEV_QFRZN;
2002
2003		if (error == ERESTART && !on_held_queue)
2004			xpt_action(ccb);
2005
2006		if (frozen != 0)
2007			cam_release_devq(ccb->ccb_h.path,
2008					 /*relsim_flags*/0,
2009					 /*opening reduction*/0,
2010					 /*timeout*/0,
2011					 /*getcount_only*/0);
2012	}
2013	return (error);
2014}
2015
2016static struct targ_cmd_desc*
2017allocdescr()
2018{
2019	struct targ_cmd_desc* descr;
2020
2021	/* Allocate the targ_descr structure */
2022	descr = (struct targ_cmd_desc *)malloc(sizeof(*descr),
2023					       M_DEVBUF, M_NOWAIT);
2024	if (descr == NULL)
2025		return (NULL);
2026
2027	bzero(descr, sizeof(*descr));
2028
2029	/* Allocate buffer backing store */
2030	descr->backing_store = malloc(MAX_BUF_SIZE, M_DEVBUF, M_NOWAIT);
2031	if (descr->backing_store == NULL) {
2032		free(descr, M_DEVBUF);
2033		return (NULL);
2034	}
2035	descr->max_size = MAX_BUF_SIZE;
2036	return (descr);
2037}
2038
2039static void
2040freedescr(struct targ_cmd_desc *descr)
2041{
2042	free(descr->backing_store, M_DEVBUF);
2043	free(descr, M_DEVBUF);
2044}
2045
2046static void
2047fill_sense(struct targ_softc *softc, u_int initiator_id, u_int error_code,
2048	   u_int sense_key, u_int asc, u_int ascq)
2049{
2050	struct initiator_state *istate;
2051	struct scsi_sense_data *sense;
2052
2053	istate = &softc->istate[initiator_id];
2054	sense = &istate->sense_data;
2055	bzero(sense, sizeof(*sense));
2056	sense->error_code = error_code;
2057	sense->flags = sense_key;
2058	sense->add_sense_code = asc;
2059	sense->add_sense_code_qual = ascq;
2060
2061	sense->extra_len = offsetof(struct scsi_sense_data, fru)
2062			 - offsetof(struct scsi_sense_data, extra_len);
2063}
2064
2065static void
2066copy_sense(struct targ_softc *softc, struct initiator_state *istate,
2067	   u_int8_t *sense_buffer, size_t sense_len)
2068{
2069	struct scsi_sense_data *sense;
2070	size_t copylen;
2071
2072	sense = &istate->sense_data;
2073	copylen = sizeof(*sense);
2074	if (copylen > sense_len)
2075		copylen = sense_len;
2076	bcopy(sense_buffer, sense, copylen);
2077}
2078
2079static void
2080set_unit_attention_cond(struct cam_periph *periph,
2081			u_int initiator_id, ua_types ua)
2082{
2083	int start;
2084	int end;
2085	struct targ_softc *softc;
2086
2087	softc = (struct targ_softc *)periph->softc;
2088	if (initiator_id == CAM_TARGET_WILDCARD) {
2089		start = 0;
2090		end = MAX_INITIATORS - 1;
2091	} else
2092		start = end = initiator_id;
2093
2094	while (start <= end) {
2095		softc->istate[start].pending_ua = ua;
2096		start++;
2097	}
2098}
2099
2100static void
2101set_ca_condition(struct cam_periph *periph, u_int initiator_id, ca_types ca)
2102{
2103	struct targ_softc *softc;
2104
2105	softc = (struct targ_softc *)periph->softc;
2106	softc->istate[initiator_id].pending_ca = ca;
2107	abort_pending_transactions(periph, initiator_id, TARG_TAG_WILDCARD,
2108				   /*errno*/0, /*to_held_queue*/TRUE);
2109}
2110
2111static void
2112abort_pending_transactions(struct cam_periph *periph, u_int initiator_id,
2113			   u_int tag_id, int errno, int to_held_queue)
2114{
2115	struct ccb_abort cab;
2116	struct ccb_queue *atio_queues[3];
2117	struct targ_softc *softc;
2118	struct ccb_hdr *ccbh;
2119	u_int i;
2120
2121	softc = (struct targ_softc *)periph->softc;
2122
2123	atio_queues[0] = &softc->work_queue;
2124	atio_queues[1] = &softc->snd_ccb_queue;
2125	atio_queues[2] = &softc->rcv_ccb_queue;
2126
2127	/* First address the ATIOs awaiting resources */
2128	for (i = 0; i < (sizeof(atio_queues) / sizeof(*atio_queues)); i++) {
2129		struct ccb_queue *atio_queue;
2130
2131		if (to_held_queue) {
2132			/*
2133			 * The device queue is frozen anyway, so there
2134			 * is nothing for us to do.
2135			 */
2136			continue;
2137		}
2138		atio_queue = atio_queues[i];
2139		ccbh = TAILQ_FIRST(atio_queue);
2140		while (ccbh != NULL) {
2141			struct ccb_accept_tio *atio;
2142			struct targ_cmd_desc *desc;
2143
2144			atio = (struct ccb_accept_tio *)ccbh;
2145			desc = (struct targ_cmd_desc *)atio->ccb_h.ccb_descr;
2146			ccbh = TAILQ_NEXT(ccbh, periph_links.tqe);
2147
2148			/* Only abort the CCBs that match */
2149			if ((atio->init_id != initiator_id
2150			  && initiator_id != CAM_TARGET_WILDCARD)
2151			 || (tag_id != TARG_TAG_WILDCARD
2152			  && ((atio->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0
2153			   || atio->tag_id != tag_id)))
2154				continue;
2155
2156			TAILQ_REMOVE(atio_queue, &atio->ccb_h,
2157				     periph_links.tqe);
2158
2159			CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
2160				  ("Aborting ATIO\n"));
2161			if (desc->bp != NULL) {
2162				desc->bp->bio_flags |= BIO_ERROR;
2163				if (softc->state != TARG_STATE_TEARDOWN)
2164					desc->bp->bio_error = errno;
2165				else
2166					desc->bp->bio_error = ENXIO;
2167				biodone(desc->bp);
2168				desc->bp = NULL;
2169			}
2170			if (softc->state == TARG_STATE_TEARDOWN) {
2171				freedescr(desc);
2172				free(atio, M_DEVBUF);
2173			} else {
2174				/* Return the ATIO back to the controller */
2175				xpt_action((union ccb *)atio);
2176			}
2177		}
2178	}
2179
2180	ccbh = TAILQ_FIRST(&softc->pending_queue);
2181	while (ccbh != NULL) {
2182		struct ccb_scsiio *csio;
2183
2184		csio = (struct ccb_scsiio *)ccbh;
2185		ccbh = TAILQ_NEXT(ccbh, periph_links.tqe);
2186
2187		/* Only abort the CCBs that match */
2188		if ((csio->init_id != initiator_id
2189		  && initiator_id != CAM_TARGET_WILDCARD)
2190		 || (tag_id != TARG_TAG_WILDCARD
2191		  && ((csio->ccb_h.flags & CAM_TAG_ACTION_VALID) == 0
2192		   || csio->tag_id != tag_id)))
2193			continue;
2194
2195		CAM_DEBUG(periph->path, CAM_DEBUG_PERIPH,
2196			  ("Aborting CTIO\n"));
2197
2198		TAILQ_REMOVE(&softc->pending_queue, &csio->ccb_h,
2199			     periph_links.tqe);
2200
2201		if (to_held_queue != 0)
2202			csio->ccb_h.ccb_flags |= TARG_CCB_ABORT_TO_HELDQ;
2203		xpt_setup_ccb(&cab.ccb_h, csio->ccb_h.path, /*priority*/1);
2204		cab.abort_ccb = (union ccb *)csio;
2205		xpt_action((union ccb *)&cab);
2206		if (cab.ccb_h.status != CAM_REQ_CMP) {
2207			xpt_print_path(cab.ccb_h.path);
2208			printf("Unable to abort CCB.  Status %x\n",
2209			       cab.ccb_h.status);
2210		}
2211	}
2212}
2213