ata_xpt.c revision 195665
1/*-
2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer,
10 *    without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/cam/ata/ata_xpt.c 195665 2009-07-13 21:21:30Z mav $");
29
30#include <sys/param.h>
31#include <sys/bus.h>
32#include <sys/endian.h>
33#include <sys/systm.h>
34#include <sys/types.h>
35#include <sys/malloc.h>
36#include <sys/kernel.h>
37#include <sys/time.h>
38#include <sys/conf.h>
39#include <sys/fcntl.h>
40#include <sys/md5.h>
41#include <sys/interrupt.h>
42#include <sys/sbuf.h>
43
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/sysctl.h>
47
48#ifdef PC98
49#include <pc98/pc98/pc98_machdep.h>	/* geometry translation */
50#endif
51
52#include <cam/cam.h>
53#include <cam/cam_ccb.h>
54#include <cam/cam_queue.h>
55#include <cam/cam_periph.h>
56#include <cam/cam_sim.h>
57#include <cam/cam_xpt.h>
58#include <cam/cam_xpt_sim.h>
59#include <cam/cam_xpt_periph.h>
60#include <cam/cam_xpt_internal.h>
61#include <cam/cam_debug.h>
62
63#include <cam/scsi/scsi_all.h>
64#include <cam/scsi/scsi_message.h>
65#include <cam/scsi/scsi_pass.h>
66#include <cam/ata/ata_all.h>
67#include <machine/stdarg.h>	/* for xpt_print below */
68#include "opt_cam.h"
69
70struct scsi_quirk_entry {
71	struct scsi_inquiry_pattern inq_pat;
72	u_int8_t quirks;
73#define	CAM_QUIRK_NOLUNS	0x01
74#define	CAM_QUIRK_NOSERIAL	0x02
75#define	CAM_QUIRK_HILUNS	0x04
76#define	CAM_QUIRK_NOHILUNS	0x08
77	u_int mintags;
78	u_int maxtags;
79};
80#define SCSI_QUIRK(dev)	((struct scsi_quirk_entry *)((dev)->quirk))
81
82static periph_init_t probe_periph_init;
83
84static struct periph_driver probe_driver =
85{
86	probe_periph_init, "aprobe",
87	TAILQ_HEAD_INITIALIZER(probe_driver.units)
88};
89
90PERIPHDRIVER_DECLARE(aprobe, probe_driver);
91
92typedef enum {
93	PROBE_RESET,
94	PROBE_IDENTIFY,
95	PROBE_SETMODE,
96	PROBE_INQUIRY,
97	PROBE_FULL_INQUIRY,
98	PROBE_PM_PID,
99	PROBE_PM_PRV,
100	PROBE_PM_PORTS,
101	PROBE_PM_RESET,
102	PROBE_PM_CONNECT,
103	PROBE_PM_CHECK,
104	PROBE_PM_CLEAR,
105	PROBE_INVALID
106} probe_action;
107
108static char *probe_action_text[] = {
109	"PROBE_RESET",
110	"PROBE_IDENTIFY",
111	"PROBE_SETMODE",
112	"PROBE_INQUIRY",
113	"PROBE_FULL_INQUIRY",
114	"PROBE_PM_PID",
115	"PROBE_PM_PRV",
116	"PROBE_PM_PORTS",
117	"PROBE_PM_RESET",
118	"PROBE_PM_CONNECT",
119	"PROBE_PM_CHECK",
120	"PROBE_PM_CLEAR",
121	"PROBE_INVALID"
122};
123
124#define PROBE_SET_ACTION(softc, newaction)	\
125do {									\
126	char **text;							\
127	text = probe_action_text;					\
128	CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO,		\
129	    ("Probe %s to %s\n", text[(softc)->action],			\
130	    text[(newaction)]));					\
131	(softc)->action = (newaction);					\
132} while(0)
133
134typedef enum {
135	PROBE_NO_ANNOUNCE	= 0x04
136} probe_flags;
137
138typedef struct {
139	TAILQ_HEAD(, ccb_hdr) request_ccbs;
140	probe_action	action;
141	union ccb	saved_ccb;
142	probe_flags	flags;
143	u_int8_t	digest[16];
144	uint32_t	pm_pid;
145	uint32_t	pm_prv;
146	int		pm_ports;
147	int		pm_step;
148	int		pm_try;
149	struct cam_periph *periph;
150} probe_softc;
151
152static struct scsi_quirk_entry scsi_quirk_table[] =
153{
154	{
155		/* Default tagged queuing parameters for all devices */
156		{
157		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
158		  /*vendor*/"*", /*product*/"*", /*revision*/"*"
159		},
160		/*quirks*/0, /*mintags*/2, /*maxtags*/32
161	},
162};
163
164static const int scsi_quirk_table_size =
165	sizeof(scsi_quirk_table) / sizeof(*scsi_quirk_table);
166
167static cam_status	proberegister(struct cam_periph *periph,
168				      void *arg);
169static void	 probeschedule(struct cam_periph *probe_periph);
170static void	 probestart(struct cam_periph *periph, union ccb *start_ccb);
171//static void	 proberequestdefaultnegotiation(struct cam_periph *periph);
172//static int       proberequestbackoff(struct cam_periph *periph,
173//				     struct cam_ed *device);
174static void	 probedone(struct cam_periph *periph, union ccb *done_ccb);
175static void	 probecleanup(struct cam_periph *periph);
176static void	 scsi_find_quirk(struct cam_ed *device);
177static void	 ata_scan_bus(struct cam_periph *periph, union ccb *ccb);
178static void	 ata_scan_lun(struct cam_periph *periph,
179			       struct cam_path *path, cam_flags flags,
180			       union ccb *ccb);
181static void	 xptscandone(struct cam_periph *periph, union ccb *done_ccb);
182static struct cam_ed *
183		 ata_alloc_device(struct cam_eb *bus, struct cam_et *target,
184				   lun_id_t lun_id);
185static void	 ata_device_transport(struct cam_path *path);
186static void	 scsi_set_transfer_settings(struct ccb_trans_settings *cts,
187					    struct cam_ed *device,
188					    int async_update);
189static void	 scsi_toggle_tags(struct cam_path *path);
190static void	 ata_dev_async(u_int32_t async_code,
191				struct cam_eb *bus,
192				struct cam_et *target,
193				struct cam_ed *device,
194				void *async_arg);
195static void	 ata_action(union ccb *start_ccb);
196
197static struct xpt_xport ata_xport = {
198	.alloc_device = ata_alloc_device,
199	.action = ata_action,
200	.async = ata_dev_async,
201};
202
203struct xpt_xport *
204ata_get_xport(void)
205{
206	return (&ata_xport);
207}
208
209static void
210probe_periph_init()
211{
212}
213
214static cam_status
215proberegister(struct cam_periph *periph, void *arg)
216{
217	union ccb *request_ccb;	/* CCB representing the probe request */
218	cam_status status;
219	probe_softc *softc;
220
221	request_ccb = (union ccb *)arg;
222	if (periph == NULL) {
223		printf("proberegister: periph was NULL!!\n");
224		return(CAM_REQ_CMP_ERR);
225	}
226
227	if (request_ccb == NULL) {
228		printf("proberegister: no probe CCB, "
229		       "can't register device\n");
230		return(CAM_REQ_CMP_ERR);
231	}
232
233	softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT);
234
235	if (softc == NULL) {
236		printf("proberegister: Unable to probe new device. "
237		       "Unable to allocate softc\n");
238		return(CAM_REQ_CMP_ERR);
239	}
240	TAILQ_INIT(&softc->request_ccbs);
241	TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
242			  periph_links.tqe);
243	softc->flags = 0;
244	periph->softc = softc;
245	softc->periph = periph;
246	softc->action = PROBE_INVALID;
247	status = cam_periph_acquire(periph);
248	if (status != CAM_REQ_CMP) {
249		return (status);
250	}
251
252
253	/*
254	 * Ensure we've waited at least a bus settle
255	 * delay before attempting to probe the device.
256	 * For HBAs that don't do bus resets, this won't make a difference.
257	 */
258	cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
259				      scsi_delay);
260	probeschedule(periph);
261	return(CAM_REQ_CMP);
262}
263
264static void
265probeschedule(struct cam_periph *periph)
266{
267	struct ccb_pathinq cpi;
268	union ccb *ccb;
269	probe_softc *softc;
270
271	softc = (probe_softc *)periph->softc;
272	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
273
274	xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
275	cpi.ccb_h.func_code = XPT_PATH_INQ;
276	xpt_action((union ccb *)&cpi);
277
278	if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
279		PROBE_SET_ACTION(softc, PROBE_RESET);
280	else if (periph->path->device->protocol == PROTO_SATAPM)
281		PROBE_SET_ACTION(softc, PROBE_PM_PID);
282	else
283		PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
284
285	if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
286		softc->flags |= PROBE_NO_ANNOUNCE;
287	else
288		softc->flags &= ~PROBE_NO_ANNOUNCE;
289
290	xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
291}
292
293static void
294probestart(struct cam_periph *periph, union ccb *start_ccb)
295{
296	/* Probe the device that our peripheral driver points to */
297	struct ccb_ataio *ataio;
298	struct ccb_scsiio *csio;
299	struct ccb_trans_settings cts;
300	probe_softc *softc;
301
302	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
303
304	softc = (probe_softc *)periph->softc;
305	ataio = &start_ccb->ataio;
306	csio = &start_ccb->csio;
307
308	switch (softc->action) {
309	case PROBE_RESET:
310		if (start_ccb->ccb_h.target_id == 15) {
311			/* Report SIM that we have no knowledge about PM presence. */
312			bzero(&cts, sizeof(cts));
313			xpt_setup_ccb(&cts.ccb_h, start_ccb->ccb_h.path, 1);
314			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
315			cts.type = CTS_TYPE_CURRENT_SETTINGS;
316			cts.xport_specific.sata.pm_present = 0;
317			cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
318			xpt_action((union ccb *)&cts);
319		}
320		cam_fill_ataio(ataio,
321		      0,
322		      probedone,
323		      /*flags*/CAM_DIR_NONE,
324		      MSG_SIMPLE_Q_TAG,
325		      /*data_ptr*/NULL,
326		      /*dxfer_len*/0,
327		      (start_ccb->ccb_h.target_id == 15 ? 3 : 15) * 1000);
328		ata_reset_cmd(ataio);
329		break;
330	case PROBE_IDENTIFY:
331	{
332		struct ata_params *ident_buf =
333		    &periph->path->device->ident_data;
334
335		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
336			/* Prepare check that it is the same device. */
337			MD5_CTX context;
338
339			MD5Init(&context);
340			MD5Update(&context,
341			    (unsigned char *)ident_buf->model,
342			    sizeof(ident_buf->model));
343			MD5Update(&context,
344			    (unsigned char *)ident_buf->revision,
345			    sizeof(ident_buf->revision));
346			MD5Update(&context,
347			    (unsigned char *)ident_buf->serial,
348			    sizeof(ident_buf->serial));
349			MD5Final(softc->digest, &context);
350		}
351		cam_fill_ataio(ataio,
352		      1,
353		      probedone,
354		      /*flags*/CAM_DIR_IN,
355		      MSG_SIMPLE_Q_TAG,
356		      /*data_ptr*/(u_int8_t *)ident_buf,
357		      /*dxfer_len*/sizeof(struct ata_params),
358		      30 * 1000);
359		if (periph->path->device->protocol == PROTO_ATA)
360			ata_36bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
361		else
362			ata_36bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
363		break;
364	}
365	case PROBE_SETMODE:
366	{
367		struct ata_params *ident_buf =
368		    &periph->path->device->ident_data;
369
370		cam_fill_ataio(ataio,
371		      1,
372		      probedone,
373		      /*flags*/CAM_DIR_IN,
374		      MSG_SIMPLE_Q_TAG,
375		      /*data_ptr*/(u_int8_t *)ident_buf,
376		      /*dxfer_len*/sizeof(struct ata_params),
377		      30 * 1000);
378		ata_36bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0,
379		    ata_max_mode(ident_buf, ATA_UDMA6, ATA_UDMA6));
380		break;
381	}
382	case PROBE_INQUIRY:
383	case PROBE_FULL_INQUIRY:
384	{
385		u_int inquiry_len;
386		struct scsi_inquiry_data *inq_buf =
387		    &periph->path->device->inq_data;
388
389		if (softc->action == PROBE_INQUIRY)
390			inquiry_len = SHORT_INQUIRY_LENGTH;
391		else
392			inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
393		/*
394		 * Some parallel SCSI devices fail to send an
395		 * ignore wide residue message when dealing with
396		 * odd length inquiry requests.  Round up to be
397		 * safe.
398		 */
399		inquiry_len = roundup2(inquiry_len, 2);
400		scsi_inquiry(csio,
401			     /*retries*/1,
402			     probedone,
403			     MSG_SIMPLE_Q_TAG,
404			     (u_int8_t *)inq_buf,
405			     inquiry_len,
406			     /*evpd*/FALSE,
407			     /*page_code*/0,
408			     SSD_MIN_SIZE,
409			     /*timeout*/60 * 1000);
410		break;
411	}
412	case PROBE_PM_PID:
413		cam_fill_ataio(ataio,
414		      1,
415		      probedone,
416		      /*flags*/CAM_DIR_NONE,
417		      MSG_SIMPLE_Q_TAG,
418		      /*data_ptr*/NULL,
419		      /*dxfer_len*/0,
420		      10 * 1000);
421		ata_pm_read_cmd(ataio, 0, 15);
422		break;
423	case PROBE_PM_PRV:
424		cam_fill_ataio(ataio,
425		      1,
426		      probedone,
427		      /*flags*/CAM_DIR_NONE,
428		      MSG_SIMPLE_Q_TAG,
429		      /*data_ptr*/NULL,
430		      /*dxfer_len*/0,
431		      10 * 1000);
432		ata_pm_read_cmd(ataio, 1, 15);
433		break;
434	case PROBE_PM_PORTS:
435		cam_fill_ataio(ataio,
436		      1,
437		      probedone,
438		      /*flags*/CAM_DIR_NONE,
439		      MSG_SIMPLE_Q_TAG,
440		      /*data_ptr*/NULL,
441		      /*dxfer_len*/0,
442		      10 * 1000);
443		ata_pm_read_cmd(ataio, 2, 15);
444		break;
445	case PROBE_PM_RESET:
446	{
447		struct ata_params *ident_buf =
448		    &periph->path->device->ident_data;
449		cam_fill_ataio(ataio,
450		      1,
451		      probedone,
452		      /*flags*/CAM_DIR_NONE,
453		      MSG_SIMPLE_Q_TAG,
454		      /*data_ptr*/NULL,
455		      /*dxfer_len*/0,
456		      10 * 1000);
457		ata_pm_write_cmd(ataio, 2, softc->pm_step,
458		    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
459printf("PM RESET %d %04x %d\n", softc->pm_step, ident_buf->cylinders,
460    (ident_buf->cylinders & (1 << softc->pm_step)) ? 0 : 1);
461		break;
462	}
463	case PROBE_PM_CONNECT:
464		cam_fill_ataio(ataio,
465		      1,
466		      probedone,
467		      /*flags*/CAM_DIR_NONE,
468		      MSG_SIMPLE_Q_TAG,
469		      /*data_ptr*/NULL,
470		      /*dxfer_len*/0,
471		      10 * 1000);
472		ata_pm_write_cmd(ataio, 2, softc->pm_step, 0);
473		break;
474	case PROBE_PM_CHECK:
475		cam_fill_ataio(ataio,
476		      1,
477		      probedone,
478		      /*flags*/CAM_DIR_NONE,
479		      MSG_SIMPLE_Q_TAG,
480		      /*data_ptr*/NULL,
481		      /*dxfer_len*/0,
482		      10 * 1000);
483		ata_pm_read_cmd(ataio, 0, softc->pm_step);
484		break;
485	case PROBE_PM_CLEAR:
486		cam_fill_ataio(ataio,
487		      1,
488		      probedone,
489		      /*flags*/CAM_DIR_NONE,
490		      MSG_SIMPLE_Q_TAG,
491		      /*data_ptr*/NULL,
492		      /*dxfer_len*/0,
493		      10 * 1000);
494		ata_pm_write_cmd(ataio, 1, softc->pm_step, 0xFFFFFFFF);
495		break;
496	case PROBE_INVALID:
497		CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
498		    ("probestart: invalid action state\n"));
499	default:
500		break;
501	}
502	xpt_action(start_ccb);
503}
504#if 0
505static void
506proberequestdefaultnegotiation(struct cam_periph *periph)
507{
508	struct ccb_trans_settings cts;
509
510	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
511	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
512	cts.type = CTS_TYPE_USER_SETTINGS;
513	xpt_action((union ccb *)&cts);
514	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
515		return;
516	}
517	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
518	cts.type = CTS_TYPE_CURRENT_SETTINGS;
519	xpt_action((union ccb *)&cts);
520}
521
522/*
523 * Backoff Negotiation Code- only pertinent for SPI devices.
524 */
525static int
526proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
527{
528	struct ccb_trans_settings cts;
529	struct ccb_trans_settings_spi *spi;
530
531	memset(&cts, 0, sizeof (cts));
532	xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
533	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
534	cts.type = CTS_TYPE_CURRENT_SETTINGS;
535	xpt_action((union ccb *)&cts);
536	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
537		if (bootverbose) {
538			xpt_print(periph->path,
539			    "failed to get current device settings\n");
540		}
541		return (0);
542	}
543	if (cts.transport != XPORT_SPI) {
544		if (bootverbose) {
545			xpt_print(periph->path, "not SPI transport\n");
546		}
547		return (0);
548	}
549	spi = &cts.xport_specific.spi;
550
551	/*
552	 * We cannot renegotiate sync rate if we don't have one.
553	 */
554	if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
555		if (bootverbose) {
556			xpt_print(periph->path, "no sync rate known\n");
557		}
558		return (0);
559	}
560
561	/*
562	 * We'll assert that we don't have to touch PPR options- the
563	 * SIM will see what we do with period and offset and adjust
564	 * the PPR options as appropriate.
565	 */
566
567	/*
568	 * A sync rate with unknown or zero offset is nonsensical.
569	 * A sync period of zero means Async.
570	 */
571	if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
572	 || spi->sync_offset == 0 || spi->sync_period == 0) {
573		if (bootverbose) {
574			xpt_print(periph->path, "no sync rate available\n");
575		}
576		return (0);
577	}
578
579	if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
580		CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
581		    ("hit async: giving up on DV\n"));
582		return (0);
583	}
584
585
586	/*
587	 * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
588	 * We don't try to remember 'last' settings to see if the SIM actually
589	 * gets into the speed we want to set. We check on the SIM telling
590	 * us that a requested speed is bad, but otherwise don't try and
591	 * check the speed due to the asynchronous and handshake nature
592	 * of speed setting.
593	 */
594	spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
595	for (;;) {
596		spi->sync_period++;
597		if (spi->sync_period >= 0xf) {
598			spi->sync_period = 0;
599			spi->sync_offset = 0;
600			CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
601			    ("setting to async for DV\n"));
602			/*
603			 * Once we hit async, we don't want to try
604			 * any more settings.
605			 */
606			device->flags |= CAM_DEV_DV_HIT_BOTTOM;
607		} else if (bootverbose) {
608			CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
609			    ("DV: period 0x%x\n", spi->sync_period));
610			printf("setting period to 0x%x\n", spi->sync_period);
611		}
612		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
613		cts.type = CTS_TYPE_CURRENT_SETTINGS;
614		xpt_action((union ccb *)&cts);
615		if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
616			break;
617		}
618		CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
619		    ("DV: failed to set period 0x%x\n", spi->sync_period));
620		if (spi->sync_period == 0) {
621			return (0);
622		}
623	}
624	return (1);
625}
626#endif
627static void
628probedone(struct cam_periph *periph, union ccb *done_ccb)
629{
630	struct ata_params *ident_buf;
631	probe_softc *softc;
632	struct cam_path *path;
633	u_int32_t  priority;
634	int found = 0;
635
636	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
637
638	softc = (probe_softc *)periph->softc;
639	path = done_ccb->ccb_h.path;
640	priority = done_ccb->ccb_h.pinfo.priority;
641	ident_buf = &path->device->ident_data;
642
643	switch (softc->action) {
644	case PROBE_RESET:
645		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
646			int sign = (done_ccb->ataio.res.lba_high << 8) +
647			    done_ccb->ataio.res.lba_mid;
648			xpt_print(path, "SIGNATURE: %04x\n", sign);
649			if (sign == 0x0000 &&
650			    done_ccb->ccb_h.target_id != 15) {
651				path->device->protocol = PROTO_ATA;
652				PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
653			} else if (sign == 0x9669 &&
654			    done_ccb->ccb_h.target_id == 15) {
655				struct ccb_trans_settings cts;
656
657				/* Report SIM that PM is present. */
658				bzero(&cts, sizeof(cts));
659				xpt_setup_ccb(&cts.ccb_h, path, 1);
660				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
661				cts.type = CTS_TYPE_CURRENT_SETTINGS;
662				cts.xport_specific.sata.pm_present = 1;
663				cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
664				xpt_action((union ccb *)&cts);
665				path->device->protocol = PROTO_SATAPM;
666				PROBE_SET_ACTION(softc, PROBE_PM_PID);
667			} else if (sign == 0xeb14 &&
668			    done_ccb->ccb_h.target_id != 15) {
669				path->device->protocol = PROTO_SCSI;
670				PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
671			} else {
672				if (done_ccb->ccb_h.target_id != 15) {
673					xpt_print(path,
674					    "Unexpected signature 0x%04x\n", sign);
675				}
676				xpt_release_ccb(done_ccb);
677				break;
678			}
679			xpt_release_ccb(done_ccb);
680			xpt_schedule(periph, priority);
681			return;
682		} else if (cam_periph_error(done_ccb, 0, 0,
683					    &softc->saved_ccb) == ERESTART) {
684			return;
685		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
686			/* Don't wedge the queue */
687			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
688					 /*run_queue*/TRUE);
689		}
690		goto device_fail;
691	case PROBE_IDENTIFY:
692	{
693		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
694			int16_t *ptr;
695
696			for (ptr = (int16_t *)ident_buf;
697			     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
698				*ptr = le16toh(*ptr);
699			}
700			if (strncmp(ident_buf->model, "FX", 2) &&
701			    strncmp(ident_buf->model, "NEC", 3) &&
702			    strncmp(ident_buf->model, "Pioneer", 7) &&
703			    strncmp(ident_buf->model, "SHARP", 5)) {
704				ata_bswap(ident_buf->model, sizeof(ident_buf->model));
705				ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
706				ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
707			}
708			ata_btrim(ident_buf->model, sizeof(ident_buf->model));
709			ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
710			ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
711			ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
712			ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
713			ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
714
715			if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
716				/* Check that it is the same device. */
717				MD5_CTX context;
718				u_int8_t digest[16];
719
720				MD5Init(&context);
721				MD5Update(&context,
722				    (unsigned char *)ident_buf->model,
723				    sizeof(ident_buf->model));
724				MD5Update(&context,
725				    (unsigned char *)ident_buf->revision,
726				    sizeof(ident_buf->revision));
727				MD5Update(&context,
728				    (unsigned char *)ident_buf->serial,
729				    sizeof(ident_buf->serial));
730				MD5Final(digest, &context);
731				if (bcmp(digest, softc->digest, sizeof(digest))) {
732					/* Device changed. */
733					xpt_async(AC_LOST_DEVICE, path, NULL);
734				}
735				xpt_release_ccb(done_ccb);
736				break;
737			}
738
739			/* Clean up from previous instance of this device */
740			if (path->device->serial_num != NULL) {
741				free(path->device->serial_num, M_CAMXPT);
742				path->device->serial_num = NULL;
743				path->device->serial_num_len = 0;
744			}
745			path->device->serial_num =
746				(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
747						   M_CAMXPT, M_NOWAIT);
748			if (path->device->serial_num != NULL) {
749				bcopy(ident_buf->serial,
750				      path->device->serial_num,
751				      sizeof(ident_buf->serial));
752				path->device->serial_num[sizeof(ident_buf->serial)]
753				    = '\0';
754				path->device->serial_num_len =
755				    strlen(path->device->serial_num);
756			}
757
758			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
759
760			scsi_find_quirk(path->device);
761			ata_device_transport(path);
762
763			PROBE_SET_ACTION(softc, PROBE_SETMODE);
764			xpt_release_ccb(done_ccb);
765			xpt_schedule(periph, priority);
766			return;
767		} else if (cam_periph_error(done_ccb, 0, 0,
768					    &softc->saved_ccb) == ERESTART) {
769			return;
770		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
771			/* Don't wedge the queue */
772			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
773					 /*run_queue*/TRUE);
774		}
775device_fail:
776		/*
777		 * If we get to this point, we got an error status back
778		 * from the inquiry and the error status doesn't require
779		 * automatically retrying the command.  Therefore, the
780		 * inquiry failed.  If we had inquiry information before
781		 * for this device, but this latest inquiry command failed,
782		 * the device has probably gone away.  If this device isn't
783		 * already marked unconfigured, notify the peripheral
784		 * drivers that this device is no more.
785		 */
786		if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
787			/* Send the async notification. */
788			xpt_async(AC_LOST_DEVICE, path, NULL);
789
790		xpt_release_ccb(done_ccb);
791		break;
792	}
793	case PROBE_SETMODE:
794	{
795		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
796			if (path->device->protocol == PROTO_ATA) {
797				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
798				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
799				xpt_action(done_ccb);
800				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
801				    done_ccb);
802				xpt_release_ccb(done_ccb);
803				break;
804			} else {
805				PROBE_SET_ACTION(softc, PROBE_INQUIRY);
806				xpt_release_ccb(done_ccb);
807				xpt_schedule(periph, priority);
808				return;
809			}
810		} else if (cam_periph_error(done_ccb, 0, 0,
811					    &softc->saved_ccb) == ERESTART) {
812			return;
813		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
814			/* Don't wedge the queue */
815			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
816					 /*run_queue*/TRUE);
817		}
818		goto device_fail;
819	}
820	case PROBE_INQUIRY:
821	case PROBE_FULL_INQUIRY:
822	{
823		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
824			struct scsi_inquiry_data *inq_buf;
825			u_int8_t periph_qual;
826
827			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
828			inq_buf = &path->device->inq_data;
829
830			periph_qual = SID_QUAL(inq_buf);
831
832			if (periph_qual == SID_QUAL_LU_CONNECTED) {
833				u_int8_t len;
834
835				/*
836				 * We conservatively request only
837				 * SHORT_INQUIRY_LEN bytes of inquiry
838				 * information during our first try
839				 * at sending an INQUIRY. If the device
840				 * has more information to give,
841				 * perform a second request specifying
842				 * the amount of information the device
843				 * is willing to give.
844				 */
845				len = inq_buf->additional_length
846				    + offsetof(struct scsi_inquiry_data,
847                                               additional_length) + 1;
848				if (softc->action == PROBE_INQUIRY
849				    && len > SHORT_INQUIRY_LENGTH) {
850					PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
851					xpt_release_ccb(done_ccb);
852					xpt_schedule(periph, priority);
853					return;
854				}
855
856				scsi_find_quirk(path->device);
857
858//				scsi_devise_transport(path);
859				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
860				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
861				xpt_action(done_ccb);
862				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
863				    done_ccb);
864				xpt_release_ccb(done_ccb);
865				break;
866			}
867		} else if (cam_periph_error(done_ccb, 0, 0,
868					    &softc->saved_ccb) == ERESTART) {
869			return;
870		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
871			/* Don't wedge the queue */
872			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
873					 /*run_queue*/TRUE);
874		}
875		goto device_fail;
876	}
877	case PROBE_PM_PID:
878		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
879			if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0)
880				bzero(ident_buf, sizeof(*ident_buf));
881			softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
882			    (done_ccb->ataio.res.lba_mid << 16) +
883			    (done_ccb->ataio.res.lba_low << 8) +
884			    done_ccb->ataio.res.sector_count;
885			printf("PM Product ID: %08x\n", softc->pm_pid);
886			snprintf(ident_buf->model, sizeof(ident_buf->model),
887			    "Port Multiplier %08x", softc->pm_pid);
888			PROBE_SET_ACTION(softc, PROBE_PM_PRV);
889			xpt_release_ccb(done_ccb);
890			xpt_schedule(periph, priority);
891			return;
892		} else if (cam_periph_error(done_ccb, 0, 0,
893					    &softc->saved_ccb) == ERESTART) {
894			return;
895		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
896			/* Don't wedge the queue */
897			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
898					 /*run_queue*/TRUE);
899		}
900		goto device_fail;
901	case PROBE_PM_PRV:
902		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
903			softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
904			    (done_ccb->ataio.res.lba_mid << 16) +
905			    (done_ccb->ataio.res.lba_low << 8) +
906			    done_ccb->ataio.res.sector_count;
907			printf("PM Revision: %08x\n", softc->pm_prv);
908			snprintf(ident_buf->revision, sizeof(ident_buf->revision),
909			    "%04x", softc->pm_prv);
910			PROBE_SET_ACTION(softc, PROBE_PM_PORTS);
911			xpt_release_ccb(done_ccb);
912			xpt_schedule(periph, priority);
913			return;
914		} else if (cam_periph_error(done_ccb, 0, 0,
915					    &softc->saved_ccb) == ERESTART) {
916			return;
917		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
918			/* Don't wedge the queue */
919			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
920					 /*run_queue*/TRUE);
921		}
922		goto device_fail;
923	case PROBE_PM_PORTS:
924		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
925			softc->pm_ports = (done_ccb->ataio.res.lba_high << 24) +
926			    (done_ccb->ataio.res.lba_mid << 16) +
927			    (done_ccb->ataio.res.lba_low << 8) +
928			    done_ccb->ataio.res.sector_count;
929			/* This PM declares 6 ports, while only 5 of them are real.
930			 * Port 5 is enclosure management bridge port, which has implementation
931			 * problems, causing probe faults. Hide it for now. */
932			if (softc->pm_pid == 0x37261095 && softc->pm_ports == 6)
933				softc->pm_ports = 5;
934			/* This PM declares 7 ports, while only 5 of them are real.
935			 * Port 5 is some fake "Config  Disk" with 640 sectors size,
936			 * port 6 is enclosure management bridge port.
937			 * Both fake ports has implementation problems, causing
938			 * probe faults. Hide them for now. */
939			if (softc->pm_pid == 0x47261095 && softc->pm_ports == 7)
940				softc->pm_ports = 5;
941			printf("PM ports: %d\n", softc->pm_ports);
942			ident_buf->config = softc->pm_ports;
943			path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
944			softc->pm_step = 0;
945			PROBE_SET_ACTION(softc, PROBE_PM_RESET);
946			xpt_release_ccb(done_ccb);
947			xpt_schedule(periph, priority);
948			return;
949		} else if (cam_periph_error(done_ccb, 0, 0,
950					    &softc->saved_ccb) == ERESTART) {
951			return;
952		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
953			/* Don't wedge the queue */
954			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
955					 /*run_queue*/TRUE);
956		}
957		goto device_fail;
958	case PROBE_PM_RESET:
959		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
960			softc->pm_step++;
961			if (softc->pm_step < softc->pm_ports) {
962				xpt_release_ccb(done_ccb);
963				xpt_schedule(periph, priority);
964				return;
965			} else {
966				softc->pm_step = 0;
967				DELAY(5000);
968				printf("PM reset done\n");
969				PROBE_SET_ACTION(softc, PROBE_PM_CONNECT);
970				xpt_release_ccb(done_ccb);
971				xpt_schedule(periph, priority);
972				return;
973			}
974		} else if (cam_periph_error(done_ccb, 0, 0,
975					    &softc->saved_ccb) == ERESTART) {
976			return;
977		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
978			/* Don't wedge the queue */
979			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
980					 /*run_queue*/TRUE);
981		}
982		goto device_fail;
983	case PROBE_PM_CONNECT:
984		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
985			softc->pm_step++;
986			if (softc->pm_step < softc->pm_ports) {
987				xpt_release_ccb(done_ccb);
988				xpt_schedule(periph, priority);
989				return;
990			} else {
991				softc->pm_step = 0;
992				softc->pm_try = 0;
993				printf("PM connect done\n");
994				PROBE_SET_ACTION(softc, PROBE_PM_CHECK);
995				xpt_release_ccb(done_ccb);
996				xpt_schedule(periph, priority);
997				return;
998			}
999		} else if (cam_periph_error(done_ccb, 0, 0,
1000					    &softc->saved_ccb) == ERESTART) {
1001			return;
1002		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1003			/* Don't wedge the queue */
1004			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1005					 /*run_queue*/TRUE);
1006		}
1007		goto device_fail;
1008	case PROBE_PM_CHECK:
1009		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1010			int res = (done_ccb->ataio.res.lba_high << 24) +
1011			    (done_ccb->ataio.res.lba_mid << 16) +
1012			    (done_ccb->ataio.res.lba_low << 8) +
1013			    done_ccb->ataio.res.sector_count;
1014			if ((res & 0xf0f) == 0x103 && (res & 0x0f0) != 0) {
1015				printf("PM status: %d - %08x\n", softc->pm_step, res);
1016				ident_buf->cylinders |= (1 << softc->pm_step);
1017				softc->pm_step++;
1018			} else {
1019				if (softc->pm_try < 100) {
1020					DELAY(10000);
1021					softc->pm_try++;
1022				} else {
1023					printf("PM status: %d - %08x\n", softc->pm_step, res);
1024					ident_buf->cylinders &= ~(1 << softc->pm_step);
1025					softc->pm_step++;
1026				}
1027			}
1028			if (softc->pm_step < softc->pm_ports) {
1029				xpt_release_ccb(done_ccb);
1030				xpt_schedule(periph, priority);
1031				return;
1032			} else {
1033				softc->pm_step = 0;
1034				PROBE_SET_ACTION(softc, PROBE_PM_CLEAR);
1035				xpt_release_ccb(done_ccb);
1036				xpt_schedule(periph, priority);
1037				return;
1038			}
1039		} else if (cam_periph_error(done_ccb, 0, 0,
1040					    &softc->saved_ccb) == ERESTART) {
1041			return;
1042		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1043			/* Don't wedge the queue */
1044			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1045					 /*run_queue*/TRUE);
1046		}
1047		goto device_fail;
1048	case PROBE_PM_CLEAR:
1049		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1050			softc->pm_step++;
1051			if (softc->pm_step < softc->pm_ports) {
1052				xpt_release_ccb(done_ccb);
1053				xpt_schedule(periph, priority);
1054				return;
1055			}
1056			found = ident_buf->cylinders | 0x8000;
1057			if (path->device->flags & CAM_DEV_UNCONFIGURED) {
1058				path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1059				done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1060				xpt_action(done_ccb);
1061				xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
1062				    done_ccb);
1063				xpt_release_ccb(done_ccb);
1064			}
1065			break;
1066		} else if (cam_periph_error(done_ccb, 0, 0,
1067					    &softc->saved_ccb) == ERESTART) {
1068			return;
1069		} else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1070			/* Don't wedge the queue */
1071			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
1072					 /*run_queue*/TRUE);
1073		}
1074		goto device_fail;
1075	case PROBE_INVALID:
1076		CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
1077		    ("probedone: invalid action state\n"));
1078	default:
1079		break;
1080	}
1081	done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
1082	TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
1083	done_ccb->ccb_h.status = CAM_REQ_CMP;
1084	done_ccb->ccb_h.ppriv_field1 = found;
1085	xpt_done(done_ccb);
1086	if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
1087		cam_periph_invalidate(periph);
1088		cam_periph_release_locked(periph);
1089	} else {
1090		probeschedule(periph);
1091	}
1092}
1093
1094static void
1095probecleanup(struct cam_periph *periph)
1096{
1097	free(periph->softc, M_CAMXPT);
1098}
1099
1100static void
1101scsi_find_quirk(struct cam_ed *device)
1102{
1103	struct scsi_quirk_entry *quirk;
1104	caddr_t	match;
1105
1106	match = cam_quirkmatch((caddr_t)&device->inq_data,
1107			       (caddr_t)scsi_quirk_table,
1108			       sizeof(scsi_quirk_table) /
1109			       sizeof(*scsi_quirk_table),
1110			       sizeof(*scsi_quirk_table), scsi_inquiry_match);
1111
1112	if (match == NULL)
1113		panic("xpt_find_quirk: device didn't match wildcard entry!!");
1114
1115	quirk = (struct scsi_quirk_entry *)match;
1116	device->quirk = quirk;
1117	device->mintags = quirk->mintags;
1118	device->maxtags = quirk->maxtags;
1119}
1120
1121typedef struct {
1122	union	ccb *request_ccb;
1123	struct 	ccb_pathinq *cpi;
1124	int	counter;
1125	int	found;
1126} ata_scan_bus_info;
1127
1128/*
1129 * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
1130 * As the scan progresses, xpt_scan_bus is used as the
1131 * callback on completion function.
1132 */
1133static void
1134ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
1135{
1136	struct	cam_path *path;
1137	ata_scan_bus_info *scan_info;
1138	union	ccb *work_ccb;
1139	cam_status status;
1140
1141	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
1142		  ("xpt_scan_bus\n"));
1143	switch (request_ccb->ccb_h.func_code) {
1144	case XPT_SCAN_BUS:
1145		/* Find out the characteristics of the bus */
1146		work_ccb = xpt_alloc_ccb_nowait();
1147		if (work_ccb == NULL) {
1148			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1149			xpt_done(request_ccb);
1150			return;
1151		}
1152		xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
1153			      request_ccb->ccb_h.pinfo.priority);
1154		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
1155		xpt_action(work_ccb);
1156		if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
1157			request_ccb->ccb_h.status = work_ccb->ccb_h.status;
1158			xpt_free_ccb(work_ccb);
1159			xpt_done(request_ccb);
1160			return;
1161		}
1162
1163		/* Save some state for use while we probe for devices */
1164		scan_info = (ata_scan_bus_info *)
1165		    malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT);
1166		if (scan_info == NULL) {
1167			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1168			xpt_done(request_ccb);
1169			return;
1170		}
1171		scan_info->request_ccb = request_ccb;
1172		scan_info->cpi = &work_ccb->cpi;
1173		scan_info->found = 0x8001;
1174		scan_info->counter = 0;
1175		/* If PM supported, probe it first. */
1176		if (scan_info->cpi->hba_inquiry & PI_SATAPM)
1177			scan_info->counter = 15;
1178
1179		work_ccb = xpt_alloc_ccb_nowait();
1180		if (work_ccb == NULL) {
1181			free(scan_info, M_CAMXPT);
1182			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1183			xpt_done(request_ccb);
1184			break;
1185		}
1186		goto scan_next;
1187	case XPT_SCAN_LUN:
1188		work_ccb = request_ccb;
1189		/* Reuse the same CCB to query if a device was really found */
1190		scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0;
1191		/* Free the current request path- we're done with it. */
1192		xpt_free_path(work_ccb->ccb_h.path);
1193		/* If there is PM... */
1194		if (scan_info->counter == 15) {
1195			if (work_ccb->ccb_h.ppriv_field1 != 0) {
1196				/* Save PM probe result. */
1197				scan_info->found = work_ccb->ccb_h.ppriv_field1;
1198			} else {
1199				struct ccb_trans_settings cts;
1200
1201				/* Report SIM that PM is absent. */
1202				bzero(&cts, sizeof(cts));
1203				xpt_setup_ccb(&cts.ccb_h,
1204				    scan_info->request_ccb->ccb_h.path, 1);
1205				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1206				cts.type = CTS_TYPE_CURRENT_SETTINGS;
1207				cts.xport_specific.sata.pm_present = 0;
1208				cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
1209				xpt_action((union ccb *)&cts);
1210			}
1211		}
1212take_next:
1213		/* Take next device. Wrap from 15 (PM) to 0. */
1214		scan_info->counter = (scan_info->counter + 1 ) & 0x0f;
1215		if (scan_info->counter >= scan_info->cpi->max_target+1) {
1216			xpt_free_ccb(work_ccb);
1217			xpt_free_ccb((union ccb *)scan_info->cpi);
1218			request_ccb = scan_info->request_ccb;
1219			free(scan_info, M_CAMXPT);
1220			request_ccb->ccb_h.status = CAM_REQ_CMP;
1221			xpt_done(request_ccb);
1222			break;
1223		}
1224scan_next:
1225		status = xpt_create_path(&path, xpt_periph,
1226		    scan_info->request_ccb->ccb_h.path_id,
1227		    scan_info->counter, 0);
1228		if (status != CAM_REQ_CMP) {
1229			printf("xpt_scan_bus: xpt_create_path failed"
1230			    " with status %#x, bus scan halted\n",
1231			    status);
1232			xpt_free_ccb(work_ccb);
1233			xpt_free_ccb((union ccb *)scan_info->cpi);
1234			request_ccb = scan_info->request_ccb;
1235			free(scan_info, M_CAMXPT);
1236			request_ccb->ccb_h.status = status;
1237			xpt_done(request_ccb);
1238			break;
1239		}
1240		if ((scan_info->found & (1 << scan_info->counter)) == 0) {
1241			xpt_async(AC_LOST_DEVICE, path, NULL);
1242			xpt_free_path(path);
1243			goto take_next;
1244		}
1245		xpt_setup_ccb(&work_ccb->ccb_h, path,
1246		    scan_info->request_ccb->ccb_h.pinfo.priority);
1247		work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1248		work_ccb->ccb_h.cbfcnp = ata_scan_bus;
1249		work_ccb->ccb_h.ppriv_ptr0 = scan_info;
1250		work_ccb->crcn.flags = scan_info->request_ccb->crcn.flags;
1251		xpt_action(work_ccb);
1252		break;
1253	default:
1254		break;
1255	}
1256}
1257
1258static void
1259ata_scan_lun(struct cam_periph *periph, struct cam_path *path,
1260	     cam_flags flags, union ccb *request_ccb)
1261{
1262	struct ccb_pathinq cpi;
1263	cam_status status;
1264	struct cam_path *new_path;
1265	struct cam_periph *old_periph;
1266
1267	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
1268		  ("xpt_scan_lun\n"));
1269
1270	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
1271	cpi.ccb_h.func_code = XPT_PATH_INQ;
1272	xpt_action((union ccb *)&cpi);
1273
1274	if (cpi.ccb_h.status != CAM_REQ_CMP) {
1275		if (request_ccb != NULL) {
1276			request_ccb->ccb_h.status = cpi.ccb_h.status;
1277			xpt_done(request_ccb);
1278		}
1279		return;
1280	}
1281
1282	if (request_ccb == NULL) {
1283		request_ccb = malloc(sizeof(union ccb), M_CAMXPT, M_NOWAIT);
1284		if (request_ccb == NULL) {
1285			xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
1286			    "can't continue\n");
1287			return;
1288		}
1289		new_path = malloc(sizeof(*new_path), M_CAMXPT, M_NOWAIT);
1290		if (new_path == NULL) {
1291			xpt_print(path, "xpt_scan_lun: can't allocate path, "
1292			    "can't continue\n");
1293			free(request_ccb, M_CAMXPT);
1294			return;
1295		}
1296		status = xpt_compile_path(new_path, xpt_periph,
1297					  path->bus->path_id,
1298					  path->target->target_id,
1299					  path->device->lun_id);
1300
1301		if (status != CAM_REQ_CMP) {
1302			xpt_print(path, "xpt_scan_lun: can't compile path, "
1303			    "can't continue\n");
1304			free(request_ccb, M_CAMXPT);
1305			free(new_path, M_CAMXPT);
1306			return;
1307		}
1308		xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
1309		request_ccb->ccb_h.cbfcnp = xptscandone;
1310		request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1311		request_ccb->crcn.flags = flags;
1312	}
1313
1314	if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
1315		probe_softc *softc;
1316
1317		softc = (probe_softc *)old_periph->softc;
1318		TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
1319				  periph_links.tqe);
1320	} else {
1321		status = cam_periph_alloc(proberegister, NULL, probecleanup,
1322					  probestart, "aprobe",
1323					  CAM_PERIPH_BIO,
1324					  request_ccb->ccb_h.path, NULL, 0,
1325					  request_ccb);
1326
1327		if (status != CAM_REQ_CMP) {
1328			xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
1329			    "returned an error, can't continue probe\n");
1330			request_ccb->ccb_h.status = status;
1331			xpt_done(request_ccb);
1332		}
1333	}
1334}
1335
1336static void
1337xptscandone(struct cam_periph *periph, union ccb *done_ccb)
1338{
1339	xpt_release_path(done_ccb->ccb_h.path);
1340	free(done_ccb->ccb_h.path, M_CAMXPT);
1341	free(done_ccb, M_CAMXPT);
1342}
1343
1344static struct cam_ed *
1345ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
1346{
1347	struct cam_path path;
1348	struct scsi_quirk_entry *quirk;
1349	struct cam_ed *device;
1350	struct cam_ed *cur_device;
1351
1352	device = xpt_alloc_device(bus, target, lun_id);
1353	if (device == NULL)
1354		return (NULL);
1355
1356	/*
1357	 * Take the default quirk entry until we have inquiry
1358	 * data and can determine a better quirk to use.
1359	 */
1360	quirk = &scsi_quirk_table[scsi_quirk_table_size - 1];
1361	device->quirk = (void *)quirk;
1362	device->mintags = quirk->mintags;
1363	device->maxtags = quirk->maxtags;
1364	bzero(&device->inq_data, sizeof(device->inq_data));
1365	device->inq_flags = 0;
1366	device->queue_flags = 0;
1367	device->serial_num = NULL;
1368	device->serial_num_len = 0;
1369
1370	/*
1371	 * XXX should be limited by number of CCBs this bus can
1372	 * do.
1373	 */
1374	bus->sim->max_ccbs += device->ccbq.devq_openings;
1375	/* Insertion sort into our target's device list */
1376	cur_device = TAILQ_FIRST(&target->ed_entries);
1377	while (cur_device != NULL && cur_device->lun_id < lun_id)
1378		cur_device = TAILQ_NEXT(cur_device, links);
1379	if (cur_device != NULL) {
1380		TAILQ_INSERT_BEFORE(cur_device, device, links);
1381	} else {
1382		TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
1383	}
1384	target->generation++;
1385	if (lun_id != CAM_LUN_WILDCARD) {
1386		xpt_compile_path(&path,
1387				 NULL,
1388				 bus->path_id,
1389				 target->target_id,
1390				 lun_id);
1391		ata_device_transport(&path);
1392		xpt_release_path(&path);
1393	}
1394
1395	return (device);
1396}
1397
1398static void
1399ata_device_transport(struct cam_path *path)
1400{
1401	struct ccb_pathinq cpi;
1402//	struct ccb_trans_settings cts;
1403	struct scsi_inquiry_data *inq_buf;
1404
1405	/* Get transport information from the SIM */
1406	xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
1407	cpi.ccb_h.func_code = XPT_PATH_INQ;
1408	xpt_action((union ccb *)&cpi);
1409
1410	inq_buf = NULL;
1411//	if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
1412//		inq_buf = &path->device->inq_data;
1413//	path->device->protocol = cpi.protocol;
1414//	path->device->protocol_version =
1415//	    inq_buf != NULL ? SID_ANSI_REV(inq_buf) : cpi.protocol_version;
1416	path->device->transport = cpi.transport;
1417	path->device->transport_version = cpi.transport_version;
1418#if 0
1419	/*
1420	 * Any device not using SPI3 features should
1421	 * be considered SPI2 or lower.
1422	 */
1423	if (inq_buf != NULL) {
1424		if (path->device->transport == XPORT_SPI
1425		 && (inq_buf->spi3data & SID_SPI_MASK) == 0
1426		 && path->device->transport_version > 2)
1427			path->device->transport_version = 2;
1428	} else {
1429		struct cam_ed* otherdev;
1430
1431		for (otherdev = TAILQ_FIRST(&path->target->ed_entries);
1432		     otherdev != NULL;
1433		     otherdev = TAILQ_NEXT(otherdev, links)) {
1434			if (otherdev != path->device)
1435				break;
1436		}
1437
1438		if (otherdev != NULL) {
1439			/*
1440			 * Initially assume the same versioning as
1441			 * prior luns for this target.
1442			 */
1443			path->device->protocol_version =
1444			    otherdev->protocol_version;
1445			path->device->transport_version =
1446			    otherdev->transport_version;
1447		} else {
1448			/* Until we know better, opt for safty */
1449			path->device->protocol_version = 2;
1450			if (path->device->transport == XPORT_SPI)
1451				path->device->transport_version = 2;
1452			else
1453				path->device->transport_version = 0;
1454		}
1455	}
1456
1457	/*
1458	 * XXX
1459	 * For a device compliant with SPC-2 we should be able
1460	 * to determine the transport version supported by
1461	 * scrutinizing the version descriptors in the
1462	 * inquiry buffer.
1463	 */
1464
1465	/* Tell the controller what we think */
1466	xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
1467	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1468	cts.type = CTS_TYPE_CURRENT_SETTINGS;
1469	cts.transport = path->device->transport;
1470	cts.transport_version = path->device->transport_version;
1471	cts.protocol = path->device->protocol;
1472	cts.protocol_version = path->device->protocol_version;
1473	cts.proto_specific.valid = 0;
1474	cts.xport_specific.valid = 0;
1475	xpt_action((union ccb *)&cts);
1476#endif
1477}
1478
1479static void
1480ata_action(union ccb *start_ccb)
1481{
1482
1483	switch (start_ccb->ccb_h.func_code) {
1484	case XPT_SET_TRAN_SETTINGS:
1485	{
1486		scsi_set_transfer_settings(&start_ccb->cts,
1487					   start_ccb->ccb_h.path->device,
1488					   /*async_update*/FALSE);
1489		break;
1490	}
1491	case XPT_SCAN_BUS:
1492		ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
1493		break;
1494	case XPT_SCAN_LUN:
1495		ata_scan_lun(start_ccb->ccb_h.path->periph,
1496			      start_ccb->ccb_h.path, start_ccb->crcn.flags,
1497			      start_ccb);
1498		break;
1499	case XPT_GET_TRAN_SETTINGS:
1500	{
1501		struct cam_sim *sim;
1502
1503		sim = start_ccb->ccb_h.path->bus->sim;
1504		(*(sim->sim_action))(sim, start_ccb);
1505		break;
1506	}
1507	default:
1508		xpt_action_default(start_ccb);
1509		break;
1510	}
1511}
1512
1513static void
1514scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
1515			   int async_update)
1516{
1517	struct	ccb_pathinq cpi;
1518	struct	ccb_trans_settings cur_cts;
1519	struct	ccb_trans_settings_scsi *scsi;
1520	struct	ccb_trans_settings_scsi *cur_scsi;
1521	struct	cam_sim *sim;
1522	struct	scsi_inquiry_data *inq_data;
1523
1524	if (device == NULL) {
1525		cts->ccb_h.status = CAM_PATH_INVALID;
1526		xpt_done((union ccb *)cts);
1527		return;
1528	}
1529
1530	if (cts->protocol == PROTO_UNKNOWN
1531	 || cts->protocol == PROTO_UNSPECIFIED) {
1532		cts->protocol = device->protocol;
1533		cts->protocol_version = device->protocol_version;
1534	}
1535
1536	if (cts->protocol_version == PROTO_VERSION_UNKNOWN
1537	 || cts->protocol_version == PROTO_VERSION_UNSPECIFIED)
1538		cts->protocol_version = device->protocol_version;
1539
1540	if (cts->protocol != device->protocol) {
1541		xpt_print(cts->ccb_h.path, "Uninitialized Protocol %x:%x?\n",
1542		       cts->protocol, device->protocol);
1543		cts->protocol = device->protocol;
1544	}
1545
1546	if (cts->protocol_version > device->protocol_version) {
1547		if (bootverbose) {
1548			xpt_print(cts->ccb_h.path, "Down reving Protocol "
1549			    "Version from %d to %d?\n", cts->protocol_version,
1550			    device->protocol_version);
1551		}
1552		cts->protocol_version = device->protocol_version;
1553	}
1554
1555	if (cts->transport == XPORT_UNKNOWN
1556	 || cts->transport == XPORT_UNSPECIFIED) {
1557		cts->transport = device->transport;
1558		cts->transport_version = device->transport_version;
1559	}
1560
1561	if (cts->transport_version == XPORT_VERSION_UNKNOWN
1562	 || cts->transport_version == XPORT_VERSION_UNSPECIFIED)
1563		cts->transport_version = device->transport_version;
1564
1565	if (cts->transport != device->transport) {
1566		xpt_print(cts->ccb_h.path, "Uninitialized Transport %x:%x?\n",
1567		    cts->transport, device->transport);
1568		cts->transport = device->transport;
1569	}
1570
1571	if (cts->transport_version > device->transport_version) {
1572		if (bootverbose) {
1573			xpt_print(cts->ccb_h.path, "Down reving Transport "
1574			    "Version from %d to %d?\n", cts->transport_version,
1575			    device->transport_version);
1576		}
1577		cts->transport_version = device->transport_version;
1578	}
1579
1580	sim = cts->ccb_h.path->bus->sim;
1581
1582	/*
1583	 * Nothing more of interest to do unless
1584	 * this is a device connected via the
1585	 * SCSI protocol.
1586	 */
1587	if (cts->protocol != PROTO_SCSI) {
1588		if (async_update == FALSE)
1589			(*(sim->sim_action))(sim, (union ccb *)cts);
1590		return;
1591	}
1592
1593	inq_data = &device->inq_data;
1594	scsi = &cts->proto_specific.scsi;
1595	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, /*priority*/1);
1596	cpi.ccb_h.func_code = XPT_PATH_INQ;
1597	xpt_action((union ccb *)&cpi);
1598
1599	/* SCSI specific sanity checking */
1600	if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
1601	 || (INQ_DATA_TQ_ENABLED(inq_data)) == 0
1602	 || (device->queue_flags & SCP_QUEUE_DQUE) != 0
1603	 || (device->mintags == 0)) {
1604		/*
1605		 * Can't tag on hardware that doesn't support tags,
1606		 * doesn't have it enabled, or has broken tag support.
1607		 */
1608		scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1609	}
1610
1611	if (async_update == FALSE) {
1612		/*
1613		 * Perform sanity checking against what the
1614		 * controller and device can do.
1615		 */
1616		xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, /*priority*/1);
1617		cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1618		cur_cts.type = cts->type;
1619		xpt_action((union ccb *)&cur_cts);
1620		if ((cur_cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1621			return;
1622		}
1623		cur_scsi = &cur_cts.proto_specific.scsi;
1624		if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
1625			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1626			scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB;
1627		}
1628		if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0)
1629			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1630	}
1631
1632	/* SPI specific sanity checking */
1633	if (cts->transport == XPORT_SPI && async_update == FALSE) {
1634		u_int spi3caps;
1635		struct ccb_trans_settings_spi *spi;
1636		struct ccb_trans_settings_spi *cur_spi;
1637
1638		spi = &cts->xport_specific.spi;
1639
1640		cur_spi = &cur_cts.xport_specific.spi;
1641
1642		/* Fill in any gaps in what the user gave us */
1643		if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
1644			spi->sync_period = cur_spi->sync_period;
1645		if ((cur_spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
1646			spi->sync_period = 0;
1647		if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
1648			spi->sync_offset = cur_spi->sync_offset;
1649		if ((cur_spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
1650			spi->sync_offset = 0;
1651		if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
1652			spi->ppr_options = cur_spi->ppr_options;
1653		if ((cur_spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
1654			spi->ppr_options = 0;
1655		if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
1656			spi->bus_width = cur_spi->bus_width;
1657		if ((cur_spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
1658			spi->bus_width = 0;
1659		if ((spi->valid & CTS_SPI_VALID_DISC) == 0) {
1660			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1661			spi->flags |= cur_spi->flags & CTS_SPI_FLAGS_DISC_ENB;
1662		}
1663		if ((cur_spi->valid & CTS_SPI_VALID_DISC) == 0)
1664			spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
1665		if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
1666		  && (inq_data->flags & SID_Sync) == 0
1667		  && cts->type == CTS_TYPE_CURRENT_SETTINGS)
1668		 || ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0)) {
1669			/* Force async */
1670			spi->sync_period = 0;
1671			spi->sync_offset = 0;
1672		}
1673
1674		switch (spi->bus_width) {
1675		case MSG_EXT_WDTR_BUS_32_BIT:
1676			if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
1677			  || (inq_data->flags & SID_WBus32) != 0
1678			  || cts->type == CTS_TYPE_USER_SETTINGS)
1679			 && (cpi.hba_inquiry & PI_WIDE_32) != 0)
1680				break;
1681			/* Fall Through to 16-bit */
1682		case MSG_EXT_WDTR_BUS_16_BIT:
1683			if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
1684			  || (inq_data->flags & SID_WBus16) != 0
1685			  || cts->type == CTS_TYPE_USER_SETTINGS)
1686			 && (cpi.hba_inquiry & PI_WIDE_16) != 0) {
1687				spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
1688				break;
1689			}
1690			/* Fall Through to 8-bit */
1691		default: /* New bus width?? */
1692		case MSG_EXT_WDTR_BUS_8_BIT:
1693			/* All targets can do this */
1694			spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
1695			break;
1696		}
1697
1698		spi3caps = cpi.xport_specific.spi.ppr_options;
1699		if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
1700		 && cts->type == CTS_TYPE_CURRENT_SETTINGS)
1701			spi3caps &= inq_data->spi3data;
1702
1703		if ((spi3caps & SID_SPI_CLOCK_DT) == 0)
1704			spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
1705
1706		if ((spi3caps & SID_SPI_IUS) == 0)
1707			spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ;
1708
1709		if ((spi3caps & SID_SPI_QAS) == 0)
1710			spi->ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
1711
1712		/* No SPI Transfer settings are allowed unless we are wide */
1713		if (spi->bus_width == 0)
1714			spi->ppr_options = 0;
1715
1716		if ((spi->valid & CTS_SPI_VALID_DISC)
1717		 && ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) == 0)) {
1718			/*
1719			 * Can't tag queue without disconnection.
1720			 */
1721			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1722			scsi->valid |= CTS_SCSI_VALID_TQ;
1723		}
1724
1725		/*
1726		 * If we are currently performing tagged transactions to
1727		 * this device and want to change its negotiation parameters,
1728		 * go non-tagged for a bit to give the controller a chance to
1729		 * negotiate unhampered by tag messages.
1730		 */
1731		if (cts->type == CTS_TYPE_CURRENT_SETTINGS
1732		 && (device->inq_flags & SID_CmdQue) != 0
1733		 && (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
1734		 && (spi->flags & (CTS_SPI_VALID_SYNC_RATE|
1735				   CTS_SPI_VALID_SYNC_OFFSET|
1736				   CTS_SPI_VALID_BUS_WIDTH)) != 0)
1737			scsi_toggle_tags(cts->ccb_h.path);
1738	}
1739
1740	if (cts->type == CTS_TYPE_CURRENT_SETTINGS
1741	 && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
1742		int device_tagenb;
1743
1744		/*
1745		 * If we are transitioning from tags to no-tags or
1746		 * vice-versa, we need to carefully freeze and restart
1747		 * the queue so that we don't overlap tagged and non-tagged
1748		 * commands.  We also temporarily stop tags if there is
1749		 * a change in transfer negotiation settings to allow
1750		 * "tag-less" negotiation.
1751		 */
1752		if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
1753		 || (device->inq_flags & SID_CmdQue) != 0)
1754			device_tagenb = TRUE;
1755		else
1756			device_tagenb = FALSE;
1757
1758		if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
1759		  && device_tagenb == FALSE)
1760		 || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0
1761		  && device_tagenb == TRUE)) {
1762
1763			if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
1764				/*
1765				 * Delay change to use tags until after a
1766				 * few commands have gone to this device so
1767				 * the controller has time to perform transfer
1768				 * negotiations without tagged messages getting
1769				 * in the way.
1770				 */
1771				device->tag_delay_count = CAM_TAG_DELAY_COUNT;
1772				device->flags |= CAM_DEV_TAG_AFTER_COUNT;
1773			} else {
1774				struct ccb_relsim crs;
1775
1776				xpt_freeze_devq(cts->ccb_h.path, /*count*/1);
1777		  		device->inq_flags &= ~SID_CmdQue;
1778				xpt_dev_ccbq_resize(cts->ccb_h.path,
1779						    sim->max_dev_openings);
1780				device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
1781				device->tag_delay_count = 0;
1782
1783				xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
1784					      /*priority*/1);
1785				crs.ccb_h.func_code = XPT_REL_SIMQ;
1786				crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
1787				crs.openings
1788				    = crs.release_timeout
1789				    = crs.qfrozen_cnt
1790				    = 0;
1791				xpt_action((union ccb *)&crs);
1792			}
1793		}
1794	}
1795	if (async_update == FALSE)
1796		(*(sim->sim_action))(sim, (union ccb *)cts);
1797}
1798
1799static void
1800scsi_toggle_tags(struct cam_path *path)
1801{
1802	struct cam_ed *dev;
1803
1804	/*
1805	 * Give controllers a chance to renegotiate
1806	 * before starting tag operations.  We
1807	 * "toggle" tagged queuing off then on
1808	 * which causes the tag enable command delay
1809	 * counter to come into effect.
1810	 */
1811	dev = path->device;
1812	if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
1813	 || ((dev->inq_flags & SID_CmdQue) != 0
1814 	  && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
1815		struct ccb_trans_settings cts;
1816
1817		xpt_setup_ccb(&cts.ccb_h, path, 1);
1818		cts.protocol = PROTO_SCSI;
1819		cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
1820		cts.transport = XPORT_UNSPECIFIED;
1821		cts.transport_version = XPORT_VERSION_UNSPECIFIED;
1822		cts.proto_specific.scsi.flags = 0;
1823		cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ;
1824		scsi_set_transfer_settings(&cts, path->device,
1825					  /*async_update*/TRUE);
1826		cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB;
1827		scsi_set_transfer_settings(&cts, path->device,
1828					  /*async_update*/TRUE);
1829	}
1830}
1831
1832/*
1833 * Handle any per-device event notifications that require action by the XPT.
1834 */
1835static void
1836ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
1837	      struct cam_ed *device, void *async_arg)
1838{
1839	cam_status status;
1840	struct cam_path newpath;
1841
1842	/*
1843	 * We only need to handle events for real devices.
1844	 */
1845	if (target->target_id == CAM_TARGET_WILDCARD
1846	 || device->lun_id == CAM_LUN_WILDCARD)
1847		return;
1848
1849	/*
1850	 * We need our own path with wildcards expanded to
1851	 * handle certain types of events.
1852	 */
1853	if ((async_code == AC_SENT_BDR)
1854	 || (async_code == AC_BUS_RESET)
1855	 || (async_code == AC_INQ_CHANGED))
1856		status = xpt_compile_path(&newpath, NULL,
1857					  bus->path_id,
1858					  target->target_id,
1859					  device->lun_id);
1860	else
1861		status = CAM_REQ_CMP_ERR;
1862
1863	if (status == CAM_REQ_CMP) {
1864
1865		/*
1866		 * Allow transfer negotiation to occur in a
1867		 * tag free environment.
1868		 */
1869		if (async_code == AC_SENT_BDR
1870		 || async_code == AC_BUS_RESET)
1871			scsi_toggle_tags(&newpath);
1872
1873		if (async_code == AC_INQ_CHANGED) {
1874			/*
1875			 * We've sent a start unit command, or
1876			 * something similar to a device that
1877			 * may have caused its inquiry data to
1878			 * change. So we re-scan the device to
1879			 * refresh the inquiry data for it.
1880			 */
1881			ata_scan_lun(newpath.periph, &newpath,
1882				     CAM_EXPECT_INQ_CHANGE, NULL);
1883		}
1884		xpt_release_path(&newpath);
1885	} else if (async_code == AC_LOST_DEVICE) {
1886		device->flags |= CAM_DEV_UNCONFIGURED;
1887	} else if (async_code == AC_TRANSFER_NEG) {
1888		struct ccb_trans_settings *settings;
1889
1890		settings = (struct ccb_trans_settings *)async_arg;
1891		scsi_set_transfer_settings(settings, device,
1892					  /*async_update*/TRUE);
1893	}
1894}
1895
1896