ata_xpt.c revision 243571
1272955Srodrigc/*-
2234949Sbapt * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3234949Sbapt * All rights reserved.
4268899Sbapt *
5234949Sbapt * Redistribution and use in source and binary forms, with or without
6234949Sbapt * modification, are permitted provided that the following conditions
7234949Sbapt * are met:
8234949Sbapt * 1. Redistributions of source code must retain the above copyright
9234949Sbapt *    notice, this list of conditions and the following disclaimer,
10234949Sbapt *    without modification, immediately at the beginning of the file.
11234949Sbapt * 2. Redistributions in binary form must reproduce the above copyright
12234949Sbapt *    notice, this list of conditions and the following disclaimer in the
13234949Sbapt *    documentation and/or other materials provided with the distribution.
14234949Sbapt *
15234949Sbapt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16234949Sbapt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17234949Sbapt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18234949Sbapt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19234949Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20234949Sbapt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21234949Sbapt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22234949Sbapt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23234949Sbapt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24234949Sbapt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25234949Sbapt */
26234949Sbapt
27234949Sbapt#include <sys/cdefs.h>
28234949Sbapt__FBSDID("$FreeBSD: head/sys/cam/ata/ata_xpt.c 243571 2012-11-26 20:07:10Z mav $");
29234949Sbapt
30234949Sbapt#include <sys/param.h>
31272953Srodrigc#include <sys/bus.h>
32251143Sbapt#include <sys/endian.h>
33251143Sbapt#include <sys/systm.h>
34251143Sbapt#include <sys/types.h>
35251143Sbapt#include <sys/malloc.h>
36251143Sbapt#include <sys/kernel.h>
37251143Sbapt#include <sys/time.h>
38251143Sbapt#include <sys/conf.h>
39251143Sbapt#include <sys/fcntl.h>
40272953Srodrigc#include <sys/interrupt.h>
41251143Sbapt#include <sys/sbuf.h>
42251143Sbapt
43251143Sbapt#include <sys/lock.h>
44251143Sbapt#include <sys/mutex.h>
45251143Sbapt#include <sys/sysctl.h>
46251143Sbapt
47251143Sbapt#include <cam/cam.h>
48251143Sbapt#include <cam/cam_ccb.h>
49251143Sbapt#include <cam/cam_queue.h>
50251143Sbapt#include <cam/cam_periph.h>
51251143Sbapt#include <cam/cam_sim.h>
52251143Sbapt#include <cam/cam_xpt.h>
53251143Sbapt#include <cam/cam_xpt_sim.h>
54251143Sbapt#include <cam/cam_xpt_periph.h>
55251143Sbapt#include <cam/cam_xpt_internal.h>
56251143Sbapt#include <cam/cam_debug.h>
57272955Srodrigc
58234949Sbapt#include <cam/scsi/scsi_all.h>
59234949Sbapt#include <cam/scsi/scsi_message.h>
60234949Sbapt#include <cam/ata/ata_all.h>
61234949Sbapt#include <machine/stdarg.h>	/* for xpt_print below */
62234949Sbapt#include "opt_cam.h"
63234949Sbapt
64234949Sbaptstruct ata_quirk_entry {
65234949Sbapt	struct scsi_inquiry_pattern inq_pat;
66234949Sbapt	u_int8_t quirks;
67234949Sbapt#define	CAM_QUIRK_MAXTAGS	0x01
68234949Sbapt	u_int mintags;
69234949Sbapt	u_int maxtags;
70234949Sbapt};
71234949Sbapt
72234949Sbaptstatic periph_init_t probe_periph_init;
73234949Sbapt
74234949Sbaptstatic struct periph_driver probe_driver =
75234949Sbapt{
76234949Sbapt	probe_periph_init, "aprobe",
77234949Sbapt	TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0,
78234949Sbapt	CAM_PERIPH_DRV_EARLY
79234949Sbapt};
80234949Sbapt
81234949SbaptPERIPHDRIVER_DECLARE(aprobe, probe_driver);
82272955Srodrigc
83234949Sbapttypedef enum {
84234949Sbapt	PROBE_RESET,
85234949Sbapt	PROBE_IDENTIFY,
86234949Sbapt	PROBE_SPINUP,
87234949Sbapt	PROBE_SETMODE,
88234949Sbapt	PROBE_SETPM,
89234949Sbapt	PROBE_SETAPST,
90234949Sbapt	PROBE_SETDMAAA,
91234949Sbapt	PROBE_SETAN,
92234949Sbapt	PROBE_SET_MULTI,
93234949Sbapt	PROBE_INQUIRY,
94234949Sbapt	PROBE_FULL_INQUIRY,
95234949Sbapt	PROBE_PM_PID,
96234949Sbapt	PROBE_PM_PRV,
97234949Sbapt	PROBE_IDENTIFY_SES,
98234949Sbapt	PROBE_IDENTIFY_SAFTE,
99234949Sbapt	PROBE_DONE,
100234949Sbapt	PROBE_INVALID
101234949Sbapt} probe_action;
102234949Sbapt
103234949Sbaptstatic char *probe_action_text[] = {
104234949Sbapt	"PROBE_RESET",
105234949Sbapt	"PROBE_IDENTIFY",
106234949Sbapt	"PROBE_SPINUP",
107234949Sbapt	"PROBE_SETMODE",
108234949Sbapt	"PROBE_SETPM",
109234949Sbapt	"PROBE_SETAPST",
110234949Sbapt	"PROBE_SETDMAAA",
111234949Sbapt	"PROBE_SETAN",
112234949Sbapt	"PROBE_SET_MULTI",
113234949Sbapt	"PROBE_INQUIRY",
114234949Sbapt	"PROBE_FULL_INQUIRY",
115234949Sbapt	"PROBE_PM_PID",
116234949Sbapt	"PROBE_PM_PRV",
117234949Sbapt	"PROBE_IDENTIFY_SES",
118234949Sbapt	"PROBE_IDENTIFY_SAFTE",
119272955Srodrigc	"PROBE_DONE",
120234949Sbapt	"PROBE_INVALID"
121234949Sbapt};
122234949Sbapt
123234949Sbapt#define PROBE_SET_ACTION(softc, newaction)	\
124234949Sbaptdo {									\
125234949Sbapt	char **text;							\
126234949Sbapt	text = probe_action_text;					\
127234949Sbapt	CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE,		\
128234949Sbapt	    ("Probe %s to %s\n", text[(softc)->action],			\
129234949Sbapt	    text[(newaction)]));					\
130234949Sbapt	(softc)->action = (newaction);					\
131234949Sbapt} while(0)
132234949Sbapt
133234949Sbapttypedef enum {
134234949Sbapt	PROBE_NO_ANNOUNCE	= 0x04
135234949Sbapt} probe_flags;
136234949Sbapt
137234949Sbapttypedef struct {
138234949Sbapt	TAILQ_HEAD(, ccb_hdr) request_ccbs;
139234949Sbapt	struct ata_params	ident_data;
140234949Sbapt	probe_action	action;
141234949Sbapt	probe_flags	flags;
142234949Sbapt	uint32_t	pm_pid;
143234949Sbapt	uint32_t	pm_prv;
144234949Sbapt	int		restart;
145234949Sbapt	int		spinup;
146234949Sbapt	int		faults;
147234949Sbapt	u_int		caps;
148234949Sbapt	struct cam_periph *periph;
149234949Sbapt} probe_softc;
150234949Sbapt
151234949Sbaptstatic struct ata_quirk_entry ata_quirk_table[] =
152234949Sbapt{
153234949Sbapt	{
154234949Sbapt		/* Default tagged queuing parameters for all devices */
155234949Sbapt		{
156234949Sbapt		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
157234949Sbapt		  /*vendor*/"*", /*product*/"*", /*revision*/"*"
158234949Sbapt		},
159234949Sbapt		/*quirks*/0, /*mintags*/0, /*maxtags*/0
160234949Sbapt	},
161234949Sbapt};
162234949Sbapt
163234949Sbaptstatic const int ata_quirk_table_size =
164234949Sbapt	sizeof(ata_quirk_table) / sizeof(*ata_quirk_table);
165234949Sbapt
166234949Sbaptstatic cam_status	proberegister(struct cam_periph *periph,
167234949Sbapt				      void *arg);
168234949Sbaptstatic void	 probeschedule(struct cam_periph *probe_periph);
169234949Sbaptstatic void	 probestart(struct cam_periph *periph, union ccb *start_ccb);
170234949Sbaptstatic void	 proberequestdefaultnegotiation(struct cam_periph *periph);
171234949Sbaptstatic void	 probedone(struct cam_periph *periph, union ccb *done_ccb);
172234949Sbaptstatic void	 probecleanup(struct cam_periph *periph);
173234949Sbaptstatic void	 ata_find_quirk(struct cam_ed *device);
174251143Sbaptstatic void	 ata_scan_bus(struct cam_periph *periph, union ccb *ccb);
175251143Sbaptstatic void	 ata_scan_lun(struct cam_periph *periph,
176251143Sbapt			       struct cam_path *path, cam_flags flags,
177251143Sbapt			       union ccb *ccb);
178251143Sbaptstatic void	 xptscandone(struct cam_periph *periph, union ccb *done_ccb);
179251143Sbaptstatic struct cam_ed *
180251143Sbapt		 ata_alloc_device(struct cam_eb *bus, struct cam_et *target,
181251143Sbapt				   lun_id_t lun_id);
182251143Sbaptstatic void	 ata_device_transport(struct cam_path *path);
183251143Sbaptstatic void	 ata_get_transfer_settings(struct ccb_trans_settings *cts);
184251143Sbaptstatic void	 ata_set_transfer_settings(struct ccb_trans_settings *cts,
185251143Sbapt					    struct cam_ed *device,
186251143Sbapt					    int async_update);
187251143Sbaptstatic void	 ata_dev_async(u_int32_t async_code,
188251143Sbapt				struct cam_eb *bus,
189251143Sbapt				struct cam_et *target,
190251143Sbapt				struct cam_ed *device,
191251143Sbapt				void *async_arg);
192251143Sbaptstatic void	 ata_action(union ccb *start_ccb);
193251143Sbaptstatic void	 ata_announce_periph(struct cam_periph *periph);
194251143Sbapt
195251143Sbaptstatic int ata_dma = 1;
196251143Sbaptstatic int atapi_dma = 1;
197251143Sbapt
198251143SbaptTUNABLE_INT("hw.ata.ata_dma", &ata_dma);
199251143SbaptTUNABLE_INT("hw.ata.atapi_dma", &atapi_dma);
200251143Sbapt
201234949Sbaptstatic struct xpt_xport ata_xport = {
202234949Sbapt	.alloc_device = ata_alloc_device,
203234949Sbapt	.action = ata_action,
204234949Sbapt	.async = ata_dev_async,
205234949Sbapt	.announce = ata_announce_periph,
206234949Sbapt};
207234949Sbapt
208234949Sbaptstruct xpt_xport *
209234949Sbaptata_get_xport(void)
210234949Sbapt{
211234949Sbapt	return (&ata_xport);
212234949Sbapt}
213234949Sbapt
214234949Sbaptstatic void
215234949Sbaptprobe_periph_init()
216234949Sbapt{
217234949Sbapt}
218234949Sbapt
219234949Sbaptstatic cam_status
220234949Sbaptproberegister(struct cam_periph *periph, void *arg)
221234949Sbapt{
222234949Sbapt	union ccb *request_ccb;	/* CCB representing the probe request */
223251143Sbapt	cam_status status;
224234949Sbapt	probe_softc *softc;
225234949Sbapt
226234949Sbapt	request_ccb = (union ccb *)arg;
227234949Sbapt	if (request_ccb == NULL) {
228234949Sbapt		printf("proberegister: no probe CCB, "
229234949Sbapt		       "can't register device\n");
230234949Sbapt		return(CAM_REQ_CMP_ERR);
231234949Sbapt	}
232234949Sbapt
233234949Sbapt	softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_ZERO | M_NOWAIT);
234234949Sbapt
235268899Sbapt	if (softc == NULL) {
236251143Sbapt		printf("proberegister: Unable to probe new device. "
237251143Sbapt		       "Unable to allocate softc\n");
238251143Sbapt		return(CAM_REQ_CMP_ERR);
239251143Sbapt	}
240251143Sbapt	TAILQ_INIT(&softc->request_ccbs);
241251143Sbapt	TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
242251143Sbapt			  periph_links.tqe);
243251143Sbapt	softc->flags = 0;
244251143Sbapt	periph->softc = softc;
245251143Sbapt	softc->periph = periph;
246268899Sbapt	softc->action = PROBE_INVALID;
247251143Sbapt	status = cam_periph_acquire(periph);
248251143Sbapt	if (status != CAM_REQ_CMP) {
249251143Sbapt		return (status);
250251143Sbapt	}
251251143Sbapt	CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n"));
252251143Sbapt
253251143Sbapt	/*
254251143Sbapt	 * Ensure nobody slip in until probe finish.
255251143Sbapt	 */
256251143Sbapt	cam_freeze_devq_arg(periph->path,
257251143Sbapt	    RELSIM_RELEASE_RUNLEVEL, CAM_RL_XPT + 1);
258251143Sbapt	probeschedule(periph);
259251143Sbapt	return(CAM_REQ_CMP);
260251143Sbapt}
261251143Sbapt
262251143Sbaptstatic void
263251143Sbaptprobeschedule(struct cam_periph *periph)
264251143Sbapt{
265251143Sbapt	union ccb *ccb;
266251143Sbapt	probe_softc *softc;
267251143Sbapt
268251143Sbapt	softc = (probe_softc *)periph->softc;
269234949Sbapt	ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
270234949Sbapt
271234949Sbapt	if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) ||
272234949Sbapt	    periph->path->device->protocol == PROTO_SATAPM ||
273234949Sbapt	    periph->path->device->protocol == PROTO_SEMB)
274234949Sbapt		PROBE_SET_ACTION(softc, PROBE_RESET);
275234949Sbapt	else
276234949Sbapt		PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
277234949Sbapt
278234949Sbapt	if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
279234949Sbapt		softc->flags |= PROBE_NO_ANNOUNCE;
280234949Sbapt	else
281234949Sbapt		softc->flags &= ~PROBE_NO_ANNOUNCE;
282234949Sbapt
283251143Sbapt	xpt_schedule(periph, CAM_PRIORITY_XPT);
284234949Sbapt}
285234949Sbapt
286234949Sbaptstatic void
287234949Sbaptprobestart(struct cam_periph *periph, union ccb *start_ccb)
288234949Sbapt{
289234949Sbapt	struct ccb_trans_settings cts;
290234949Sbapt	struct ccb_ataio *ataio;
291234949Sbapt	struct ccb_scsiio *csio;
292234949Sbapt	probe_softc *softc;
293234949Sbapt	struct cam_path *path;
294234949Sbapt	struct ata_params *ident_buf;
295234949Sbapt
296234949Sbapt	CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
297234949Sbapt
298234949Sbapt	softc = (probe_softc *)periph->softc;
299234949Sbapt	path = start_ccb->ccb_h.path;
300234949Sbapt	ataio = &start_ccb->ataio;
301234949Sbapt	csio = &start_ccb->csio;
302234949Sbapt	ident_buf = &periph->path->device->ident_data;
303234949Sbapt
304234949Sbapt	if (softc->restart) {
305251143Sbapt		softc->restart = 0;
306234949Sbapt		if ((path->device->flags & CAM_DEV_UNCONFIGURED) ||
307234949Sbapt		    path->device->protocol == PROTO_SATAPM ||
308234949Sbapt		    path->device->protocol == PROTO_SEMB)
309234949Sbapt			softc->action = PROBE_RESET;
310234949Sbapt		else
311234949Sbapt			softc->action = PROBE_IDENTIFY;
312234949Sbapt	}
313234949Sbapt	switch (softc->action) {
314234949Sbapt	case PROBE_RESET:
315234949Sbapt		cam_fill_ataio(ataio,
316234949Sbapt		      0,
317234949Sbapt		      probedone,
318234949Sbapt		      /*flags*/CAM_DIR_NONE,
319234949Sbapt		      0,
320234949Sbapt		      /*data_ptr*/NULL,
321234949Sbapt		      /*dxfer_len*/0,
322234949Sbapt		      15 * 1000);
323251143Sbapt		ata_reset_cmd(ataio);
324251143Sbapt		break;
325234949Sbapt	case PROBE_IDENTIFY:
326234949Sbapt		cam_fill_ataio(ataio,
327234949Sbapt		      1,
328251143Sbapt		      probedone,
329234949Sbapt		      /*flags*/CAM_DIR_IN,
330234949Sbapt		      0,
331234949Sbapt		      /*data_ptr*/(u_int8_t *)&softc->ident_data,
332234949Sbapt		      /*dxfer_len*/sizeof(softc->ident_data),
333234949Sbapt		      30 * 1000);
334234949Sbapt		if (periph->path->device->protocol == PROTO_ATA)
335234949Sbapt			ata_28bit_cmd(ataio, ATA_ATA_IDENTIFY, 0, 0, 0);
336234949Sbapt		else
337234949Sbapt			ata_28bit_cmd(ataio, ATA_ATAPI_IDENTIFY, 0, 0, 0);
338234949Sbapt		break;
339234949Sbapt	case PROBE_SPINUP:
340234949Sbapt		if (bootverbose)
341234949Sbapt			xpt_print(path, "Spinning up device\n");
342234949Sbapt		cam_fill_ataio(ataio,
343234949Sbapt		      1,
344234949Sbapt		      probedone,
345234949Sbapt		      /*flags*/CAM_DIR_NONE | CAM_HIGH_POWER,
346234949Sbapt		      0,
347234949Sbapt		      /*data_ptr*/NULL,
348234949Sbapt		      /*dxfer_len*/0,
349234949Sbapt		      30 * 1000);
350234949Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_PUIS_SPINUP, 0, 0);
351234949Sbapt		break;
352234949Sbapt	case PROBE_SETMODE:
353234949Sbapt	{
354234949Sbapt		int mode, wantmode;
355234949Sbapt
356234949Sbapt		mode = 0;
357234949Sbapt		/* Fetch user modes from SIM. */
358234949Sbapt		bzero(&cts, sizeof(cts));
359234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
360234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
361234949Sbapt		cts.type = CTS_TYPE_USER_SETTINGS;
362234949Sbapt		xpt_action((union ccb *)&cts);
363234949Sbapt		if (path->device->transport == XPORT_ATA) {
364234949Sbapt			if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE)
365234949Sbapt				mode = cts.xport_specific.ata.mode;
366234949Sbapt		} else {
367234949Sbapt			if (cts.xport_specific.sata.valid & CTS_SATA_VALID_MODE)
368234949Sbapt				mode = cts.xport_specific.sata.mode;
369234949Sbapt		}
370234949Sbapt		if (periph->path->device->protocol == PROTO_ATA) {
371234949Sbapt			if (ata_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX))
372234949Sbapt				mode = ATA_PIO_MAX;
373234949Sbapt		} else {
374234949Sbapt			if (atapi_dma == 0 && (mode == 0 || mode > ATA_PIO_MAX))
375234949Sbapt				mode = ATA_PIO_MAX;
376234949Sbapt		}
377234949Sbaptnegotiate:
378234949Sbapt		/* Honor device capabilities. */
379234949Sbapt		wantmode = mode = ata_max_mode(ident_buf, mode);
380234949Sbapt		/* Report modes to SIM. */
381234949Sbapt		bzero(&cts, sizeof(cts));
382234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
383234949Sbapt		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
384234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
385234949Sbapt		if (path->device->transport == XPORT_ATA) {
386234949Sbapt			cts.xport_specific.ata.mode = mode;
387234949Sbapt			cts.xport_specific.ata.valid = CTS_ATA_VALID_MODE;
388234949Sbapt		} else {
389234949Sbapt			cts.xport_specific.sata.mode = mode;
390234949Sbapt			cts.xport_specific.sata.valid = CTS_SATA_VALID_MODE;
391234949Sbapt		}
392234949Sbapt		xpt_action((union ccb *)&cts);
393234949Sbapt		/* Fetch current modes from SIM. */
394234949Sbapt		bzero(&cts, sizeof(cts));
395234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
396234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
397234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
398234949Sbapt		xpt_action((union ccb *)&cts);
399234949Sbapt		if (path->device->transport == XPORT_ATA) {
400234949Sbapt			if (cts.xport_specific.ata.valid & CTS_ATA_VALID_MODE)
401234949Sbapt				mode = cts.xport_specific.ata.mode;
402234949Sbapt		} else {
403234949Sbapt			if (cts.xport_specific.ata.valid & CTS_SATA_VALID_MODE)
404234949Sbapt				mode = cts.xport_specific.sata.mode;
405234949Sbapt		}
406251143Sbapt		/* If SIM disagree - renegotiate. */
407251143Sbapt		if (mode != wantmode)
408251143Sbapt			goto negotiate;
409234949Sbapt		/* Remember what transport thinks about DMA. */
410251143Sbapt		if (mode < ATA_DMA)
411251143Sbapt			path->device->inq_flags &= ~SID_DMA;
412251143Sbapt		else
413251143Sbapt			path->device->inq_flags |= SID_DMA;
414234949Sbapt		xpt_async(AC_GETDEV_CHANGED, path, NULL);
415251143Sbapt		cam_fill_ataio(ataio,
416234949Sbapt		      1,
417234949Sbapt		      probedone,
418251143Sbapt		      /*flags*/CAM_DIR_NONE,
419251143Sbapt		      0,
420251143Sbapt		      /*data_ptr*/NULL,
421251143Sbapt		      /*dxfer_len*/0,
422234949Sbapt		      30 * 1000);
423251143Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES, ATA_SF_SETXFER, 0, mode);
424234949Sbapt		break;
425251143Sbapt	}
426251143Sbapt	case PROBE_SETPM:
427251143Sbapt		cam_fill_ataio(ataio,
428234949Sbapt		    1,
429234949Sbapt		    probedone,
430234949Sbapt		    CAM_DIR_NONE,
431234949Sbapt		    0,
432234949Sbapt		    NULL,
433234949Sbapt		    0,
434234949Sbapt		    30*1000);
435234949Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES,
436234949Sbapt		    (softc->caps & CTS_SATA_CAPS_H_PMREQ) ? 0x10 : 0x90,
437234949Sbapt		    0, 0x03);
438251143Sbapt		break;
439234949Sbapt	case PROBE_SETAPST:
440234949Sbapt		cam_fill_ataio(ataio,
441234949Sbapt		    1,
442234949Sbapt		    probedone,
443234949Sbapt		    CAM_DIR_NONE,
444234949Sbapt		    0,
445234949Sbapt		    NULL,
446251143Sbapt		    0,
447234949Sbapt		    30*1000);
448234949Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES,
449234949Sbapt		    (softc->caps & CTS_SATA_CAPS_H_APST) ? 0x10 : 0x90,
450234949Sbapt		    0, 0x07);
451234949Sbapt		break;
452268899Sbapt	case PROBE_SETDMAAA:
453234949Sbapt		cam_fill_ataio(ataio,
454234949Sbapt		    1,
455234949Sbapt		    probedone,
456234949Sbapt		    CAM_DIR_NONE,
457234949Sbapt		    0,
458234949Sbapt		    NULL,
459234949Sbapt		    0,
460234949Sbapt		    30*1000);
461234949Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES,
462234949Sbapt		    (softc->caps & CTS_SATA_CAPS_H_DMAAA) ? 0x10 : 0x90,
463234949Sbapt		    0, 0x02);
464234949Sbapt		break;
465234949Sbapt	case PROBE_SETAN:
466234949Sbapt		/* Remember what transport thinks about AEN. */
467234949Sbapt		if (softc->caps & CTS_SATA_CAPS_H_AN)
468234949Sbapt			path->device->inq_flags |= SID_AEN;
469234949Sbapt		else
470234949Sbapt			path->device->inq_flags &= ~SID_AEN;
471234949Sbapt		xpt_async(AC_GETDEV_CHANGED, path, NULL);
472234949Sbapt		cam_fill_ataio(ataio,
473234949Sbapt		    1,
474234949Sbapt		    probedone,
475251143Sbapt		    CAM_DIR_NONE,
476234949Sbapt		    0,
477234949Sbapt		    NULL,
478234949Sbapt		    0,
479234949Sbapt		    30*1000);
480234949Sbapt		ata_28bit_cmd(ataio, ATA_SETFEATURES,
481234949Sbapt		    (softc->caps & CTS_SATA_CAPS_H_AN) ? 0x10 : 0x90,
482234949Sbapt		    0, 0x05);
483234949Sbapt		break;
484234949Sbapt	case PROBE_SET_MULTI:
485234949Sbapt	{
486234949Sbapt		u_int sectors, bytecount;
487234949Sbapt
488234949Sbapt		bytecount = 8192;	/* SATA maximum */
489234949Sbapt		/* Fetch user bytecount from SIM. */
490234949Sbapt		bzero(&cts, sizeof(cts));
491234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
492234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
493234949Sbapt		cts.type = CTS_TYPE_USER_SETTINGS;
494234949Sbapt		xpt_action((union ccb *)&cts);
495234949Sbapt		if (path->device->transport == XPORT_ATA) {
496234949Sbapt			if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
497234949Sbapt				bytecount = cts.xport_specific.ata.bytecount;
498234949Sbapt		} else {
499234949Sbapt			if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
500234949Sbapt				bytecount = cts.xport_specific.sata.bytecount;
501234949Sbapt		}
502234949Sbapt		/* Honor device capabilities. */
503234949Sbapt		sectors = max(1, min(ident_buf->sectors_intr & 0xff,
504234949Sbapt		    bytecount / ata_logical_sector_size(ident_buf)));
505234949Sbapt		/* Report bytecount to SIM. */
506234949Sbapt		bzero(&cts, sizeof(cts));
507234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
508234949Sbapt		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
509234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
510234949Sbapt		if (path->device->transport == XPORT_ATA) {
511234949Sbapt			cts.xport_specific.ata.bytecount = sectors *
512234949Sbapt			    ata_logical_sector_size(ident_buf);
513234949Sbapt			cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
514234949Sbapt		} else {
515234949Sbapt			cts.xport_specific.sata.bytecount = sectors *
516234949Sbapt			    ata_logical_sector_size(ident_buf);
517234949Sbapt			cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
518234949Sbapt		}
519234949Sbapt		xpt_action((union ccb *)&cts);
520234949Sbapt		/* Fetch current bytecount from SIM. */
521234949Sbapt		bzero(&cts, sizeof(cts));
522234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
523234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
524268899Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
525268899Sbapt		xpt_action((union ccb *)&cts);
526234949Sbapt		if (path->device->transport == XPORT_ATA) {
527234949Sbapt			if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
528234949Sbapt				bytecount = cts.xport_specific.ata.bytecount;
529234949Sbapt		} else {
530268899Sbapt			if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
531268899Sbapt				bytecount = cts.xport_specific.sata.bytecount;
532234949Sbapt		}
533234949Sbapt		sectors = bytecount / ata_logical_sector_size(ident_buf);
534234949Sbapt
535234949Sbapt		cam_fill_ataio(ataio,
536234949Sbapt		    1,
537234949Sbapt		    probedone,
538234949Sbapt		    CAM_DIR_NONE,
539268899Sbapt		    0,
540234949Sbapt		    NULL,
541234949Sbapt		    0,
542234949Sbapt		    30*1000);
543234949Sbapt		ata_28bit_cmd(ataio, ATA_SET_MULTI, 0, 0, sectors);
544234949Sbapt		break;
545234949Sbapt	}
546234949Sbapt	case PROBE_INQUIRY:
547234949Sbapt	{
548234949Sbapt		u_int bytecount;
549234949Sbapt
550234949Sbapt		bytecount = 8192;	/* SATA maximum */
551234949Sbapt		/* Fetch user bytecount from SIM. */
552234949Sbapt		bzero(&cts, sizeof(cts));
553234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
554234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
555251143Sbapt		cts.type = CTS_TYPE_USER_SETTINGS;
556251143Sbapt		xpt_action((union ccb *)&cts);
557251143Sbapt		if (path->device->transport == XPORT_ATA) {
558251143Sbapt			if (cts.xport_specific.ata.valid & CTS_ATA_VALID_BYTECOUNT)
559251143Sbapt				bytecount = cts.xport_specific.ata.bytecount;
560251143Sbapt		} else {
561251143Sbapt			if (cts.xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
562234949Sbapt				bytecount = cts.xport_specific.sata.bytecount;
563234949Sbapt		}
564234949Sbapt		/* Honor device capabilities. */
565234949Sbapt		bytecount &= ~1;
566234949Sbapt		bytecount = max(2, min(65534, bytecount));
567234949Sbapt		if (ident_buf->satacapabilities != 0x0000 &&
568234949Sbapt		    ident_buf->satacapabilities != 0xffff) {
569234949Sbapt			bytecount = min(8192, bytecount);
570234949Sbapt		}
571234949Sbapt		/* Report bytecount to SIM. */
572234949Sbapt		bzero(&cts, sizeof(cts));
573234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
574234949Sbapt		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
575234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
576234949Sbapt		if (path->device->transport == XPORT_ATA) {
577234949Sbapt			cts.xport_specific.ata.bytecount = bytecount;
578234949Sbapt			cts.xport_specific.ata.valid = CTS_ATA_VALID_BYTECOUNT;
579234949Sbapt		} else {
580234949Sbapt			cts.xport_specific.sata.bytecount = bytecount;
581234949Sbapt			cts.xport_specific.sata.valid = CTS_SATA_VALID_BYTECOUNT;
582234949Sbapt		}
583234949Sbapt		xpt_action((union ccb *)&cts);
584234949Sbapt		/* FALLTHROUGH */
585234949Sbapt	}
586234949Sbapt	case PROBE_FULL_INQUIRY:
587234949Sbapt	{
588234949Sbapt		u_int inquiry_len;
589234949Sbapt		struct scsi_inquiry_data *inq_buf =
590234949Sbapt		    &periph->path->device->inq_data;
591234949Sbapt
592234949Sbapt		if (softc->action == PROBE_INQUIRY)
593234949Sbapt			inquiry_len = SHORT_INQUIRY_LENGTH;
594234949Sbapt		else
595234949Sbapt			inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
596234949Sbapt		/*
597234949Sbapt		 * Some parallel SCSI devices fail to send an
598234949Sbapt		 * ignore wide residue message when dealing with
599234949Sbapt		 * odd length inquiry requests.  Round up to be
600234949Sbapt		 * safe.
601234949Sbapt		 */
602234949Sbapt		inquiry_len = roundup2(inquiry_len, 2);
603268899Sbapt		scsi_inquiry(csio,
604234949Sbapt			     /*retries*/1,
605234949Sbapt			     probedone,
606234949Sbapt			     MSG_SIMPLE_Q_TAG,
607234949Sbapt			     (u_int8_t *)inq_buf,
608234949Sbapt			     inquiry_len,
609234949Sbapt			     /*evpd*/FALSE,
610234949Sbapt			     /*page_code*/0,
611234949Sbapt			     SSD_MIN_SIZE,
612234949Sbapt			     /*timeout*/60 * 1000);
613234949Sbapt		break;
614234949Sbapt	}
615234949Sbapt	case PROBE_PM_PID:
616234949Sbapt		cam_fill_ataio(ataio,
617251143Sbapt		      1,
618234949Sbapt		      probedone,
619234949Sbapt		      /*flags*/CAM_DIR_NONE,
620234949Sbapt		      0,
621234949Sbapt		      /*data_ptr*/NULL,
622234949Sbapt		      /*dxfer_len*/0,
623234949Sbapt		      10 * 1000);
624234949Sbapt		ata_pm_read_cmd(ataio, 0, 15);
625234949Sbapt		break;
626234949Sbapt	case PROBE_PM_PRV:
627234949Sbapt		cam_fill_ataio(ataio,
628234949Sbapt		      1,
629234949Sbapt		      probedone,
630234949Sbapt		      /*flags*/CAM_DIR_NONE,
631234949Sbapt		      0,
632268899Sbapt		      /*data_ptr*/NULL,
633234949Sbapt		      /*dxfer_len*/0,
634234949Sbapt		      10 * 1000);
635234949Sbapt		ata_pm_read_cmd(ataio, 1, 15);
636234949Sbapt		break;
637234949Sbapt	case PROBE_IDENTIFY_SES:
638234949Sbapt		cam_fill_ataio(ataio,
639234949Sbapt		      1,
640234949Sbapt		      probedone,
641268899Sbapt		      /*flags*/CAM_DIR_IN,
642268899Sbapt		      0,
643268899Sbapt		      /*data_ptr*/(u_int8_t *)&softc->ident_data,
644268899Sbapt		      /*dxfer_len*/sizeof(softc->ident_data),
645268899Sbapt		      30 * 1000);
646268899Sbapt		ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x02,
647268899Sbapt		    sizeof(softc->ident_data) / 4);
648268899Sbapt		break;
649268899Sbapt	case PROBE_IDENTIFY_SAFTE:
650268899Sbapt		cam_fill_ataio(ataio,
651268899Sbapt		      1,
652268899Sbapt		      probedone,
653268899Sbapt		      /*flags*/CAM_DIR_IN,
654268899Sbapt		      0,
655268899Sbapt		      /*data_ptr*/(u_int8_t *)&softc->ident_data,
656268899Sbapt		      /*dxfer_len*/sizeof(softc->ident_data),
657268899Sbapt		      30 * 1000);
658268899Sbapt		ata_28bit_cmd(ataio, ATA_SEP_ATTN, 0xEC, 0x00,
659268899Sbapt		    sizeof(softc->ident_data) / 4);
660268899Sbapt		break;
661268899Sbapt	default:
662268899Sbapt		panic("probestart: invalid action state 0x%x\n", softc->action);
663268899Sbapt	}
664268899Sbapt	xpt_action(start_ccb);
665268899Sbapt}
666268899Sbapt
667268899Sbaptstatic void
668268899Sbaptproberequestdefaultnegotiation(struct cam_periph *periph)
669268899Sbapt{
670268899Sbapt	struct ccb_trans_settings cts;
671268899Sbapt
672268899Sbapt	xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
673268899Sbapt	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
674268899Sbapt	cts.type = CTS_TYPE_USER_SETTINGS;
675268899Sbapt	xpt_action((union ccb *)&cts);
676268899Sbapt	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
677268899Sbapt		return;
678268899Sbapt	cts.xport_specific.valid = 0;
679268899Sbapt	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
680268899Sbapt	cts.type = CTS_TYPE_CURRENT_SETTINGS;
681268899Sbapt	xpt_action((union ccb *)&cts);
682268899Sbapt}
683268899Sbapt
684268899Sbaptstatic void
685268899Sbaptprobedone(struct cam_periph *periph, union ccb *done_ccb)
686268899Sbapt{
687268899Sbapt	struct ccb_trans_settings cts;
688268899Sbapt	struct ata_params *ident_buf;
689268899Sbapt	struct scsi_inquiry_data *inq_buf;
690268899Sbapt	probe_softc *softc;
691268899Sbapt	struct cam_path *path;
692268899Sbapt	cam_status status;
693268899Sbapt	u_int32_t  priority;
694268899Sbapt	u_int caps;
695234949Sbapt	int changed = 1, found = 1;
696234949Sbapt	static const uint8_t fake_device_id_hdr[8] =
697234949Sbapt	    {0, SVPD_DEVICE_ID, 0, 12,
698234949Sbapt	     SVPD_ID_CODESET_BINARY, SVPD_ID_TYPE_NAA, 0, 8};
699234949Sbapt
700234949Sbapt	CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
701234949Sbapt
702234949Sbapt	softc = (probe_softc *)periph->softc;
703234949Sbapt	path = done_ccb->ccb_h.path;
704234949Sbapt	priority = done_ccb->ccb_h.pinfo.priority;
705234949Sbapt	ident_buf = &path->device->ident_data;
706234949Sbapt	inq_buf = &path->device->inq_data;
707234949Sbapt
708234949Sbapt	if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
709234949Sbapt		if (cam_periph_error(done_ccb,
710234949Sbapt		    0, softc->restart ? (SF_NO_RECOVERY | SF_NO_RETRY) : 0,
711234949Sbapt		    NULL) == ERESTART)
712234949Sbapt			return;
713234949Sbapt		if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
714234949Sbapt			/* Don't wedge the queue */
715234949Sbapt			xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
716234949Sbapt					 /*run_queue*/TRUE);
717234949Sbapt		}
718234949Sbapt		status = done_ccb->ccb_h.status & CAM_STATUS_MASK;
719234949Sbapt		if (softc->restart) {
720234949Sbapt			softc->faults++;
721234949Sbapt			if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) ==
722234949Sbapt			    CAM_CMD_TIMEOUT)
723234949Sbapt				softc->faults += 4;
724234949Sbapt			if (softc->faults < 10)
725234949Sbapt				goto done;
726234949Sbapt			else
727234949Sbapt				softc->restart = 0;
728234949Sbapt
729234949Sbapt		/* Old PIO2 devices may not support mode setting. */
730234949Sbapt		} else if (softc->action == PROBE_SETMODE &&
731234949Sbapt		    status == CAM_ATA_STATUS_ERROR &&
732268899Sbapt		    ata_max_pmode(ident_buf) <= ATA_PIO2 &&
733234949Sbapt		    (ident_buf->capabilities1 & ATA_SUPPORT_IORDY) == 0) {
734234949Sbapt			goto noerror;
735234949Sbapt
736234949Sbapt		/*
737234949Sbapt		 * Some old WD SATA disks report supported and enabled
738234949Sbapt		 * device-initiated interface power management, but return
739234949Sbapt		 * ABORT on attempt to disable it.
740234949Sbapt		 */
741268899Sbapt		} else if (softc->action == PROBE_SETPM &&
742234949Sbapt		    status == CAM_ATA_STATUS_ERROR) {
743234949Sbapt			goto noerror;
744234949Sbapt
745234949Sbapt		/*
746234949Sbapt		 * Some HP SATA disks report supported DMA Auto-Activation,
747234949Sbapt		 * but return ABORT on attempt to enable it.
748234949Sbapt		 */
749234949Sbapt		} else if (softc->action == PROBE_SETDMAAA &&
750234949Sbapt		    status == CAM_ATA_STATUS_ERROR) {
751234949Sbapt			goto noerror;
752234949Sbapt
753234949Sbapt		/*
754234949Sbapt		 * Some Samsung SSDs report supported Asynchronous Notification,
755234949Sbapt		 * but return ABORT on attempt to enable it.
756234949Sbapt		 */
757234949Sbapt		} else if (softc->action == PROBE_SETAN &&
758234949Sbapt		    status == CAM_ATA_STATUS_ERROR) {
759251143Sbapt			goto noerror;
760234949Sbapt
761234949Sbapt		/*
762251143Sbapt		 * SES and SAF-TE SEPs have different IDENTIFY commands,
763234949Sbapt		 * but SATA specification doesn't tell how to identify them.
764234949Sbapt		 * Until better way found, just try another if first fail.
765234949Sbapt		 */
766234949Sbapt		} else if (softc->action == PROBE_IDENTIFY_SES &&
767234949Sbapt		    status == CAM_ATA_STATUS_ERROR) {
768234949Sbapt			PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SAFTE);
769234949Sbapt			xpt_release_ccb(done_ccb);
770234949Sbapt			xpt_schedule(periph, priority);
771234949Sbapt			return;
772234949Sbapt		}
773234949Sbapt
774234949Sbapt		/*
775234949Sbapt		 * If we get to this point, we got an error status back
776234949Sbapt		 * from the inquiry and the error status doesn't require
777234949Sbapt		 * automatically retrying the command.  Therefore, the
778234949Sbapt		 * inquiry failed.  If we had inquiry information before
779234949Sbapt		 * for this device, but this latest inquiry command failed,
780234949Sbapt		 * the device has probably gone away.  If this device isn't
781234949Sbapt		 * already marked unconfigured, notify the peripheral
782234949Sbapt		 * drivers that this device is no more.
783234949Sbapt		 */
784234949Sbaptdevice_fail:	if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
785234949Sbapt			xpt_async(AC_LOST_DEVICE, path, NULL);
786234949Sbapt		PROBE_SET_ACTION(softc, PROBE_INVALID);
787234949Sbapt		found = 0;
788234949Sbapt		goto done;
789234949Sbapt	}
790234949Sbaptnoerror:
791234949Sbapt	if (softc->restart)
792234949Sbapt		goto done;
793234949Sbapt	switch (softc->action) {
794234949Sbapt	case PROBE_RESET:
795234949Sbapt	{
796234949Sbapt		int sign = (done_ccb->ataio.res.lba_high << 8) +
797234949Sbapt		    done_ccb->ataio.res.lba_mid;
798234949Sbapt		CAM_DEBUG(path, CAM_DEBUG_PROBE,
799234949Sbapt		    ("SIGNATURE: %04x\n", sign));
800234949Sbapt		if (sign == 0x0000 &&
801234949Sbapt		    done_ccb->ccb_h.target_id != 15) {
802234949Sbapt			path->device->protocol = PROTO_ATA;
803234949Sbapt			PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
804251143Sbapt		} else if (sign == 0x9669 &&
805234949Sbapt		    done_ccb->ccb_h.target_id == 15) {
806251143Sbapt			/* Report SIM that PM is present. */
807251143Sbapt			bzero(&cts, sizeof(cts));
808251143Sbapt			xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
809234949Sbapt			cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
810251143Sbapt			cts.type = CTS_TYPE_CURRENT_SETTINGS;
811234949Sbapt			cts.xport_specific.sata.pm_present = 1;
812234949Sbapt			cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
813234949Sbapt			xpt_action((union ccb *)&cts);
814234949Sbapt			path->device->protocol = PROTO_SATAPM;
815234949Sbapt			PROBE_SET_ACTION(softc, PROBE_PM_PID);
816234949Sbapt		} else if (sign == 0xc33c &&
817234949Sbapt		    done_ccb->ccb_h.target_id != 15) {
818234949Sbapt			path->device->protocol = PROTO_SEMB;
819234949Sbapt			PROBE_SET_ACTION(softc, PROBE_IDENTIFY_SES);
820234949Sbapt		} else if (sign == 0xeb14 &&
821234949Sbapt		    done_ccb->ccb_h.target_id != 15) {
822251143Sbapt			path->device->protocol = PROTO_SCSI;
823234949Sbapt			PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
824234949Sbapt		} else {
825234949Sbapt			if (done_ccb->ccb_h.target_id != 15) {
826234949Sbapt				xpt_print(path,
827234949Sbapt				    "Unexpected signature 0x%04x\n", sign);
828234949Sbapt			}
829251143Sbapt			goto device_fail;
830234949Sbapt		}
831234949Sbapt		xpt_release_ccb(done_ccb);
832234949Sbapt		xpt_schedule(periph, priority);
833234949Sbapt		return;
834234949Sbapt	}
835234949Sbapt	case PROBE_IDENTIFY:
836234949Sbapt	{
837234949Sbapt		struct ccb_pathinq cpi;
838234949Sbapt		int16_t *ptr;
839234949Sbapt
840234949Sbapt		ident_buf = &softc->ident_data;
841234949Sbapt		for (ptr = (int16_t *)ident_buf;
842234949Sbapt		     ptr < (int16_t *)ident_buf + sizeof(struct ata_params)/2; ptr++) {
843234949Sbapt			*ptr = le16toh(*ptr);
844234949Sbapt		}
845234949Sbapt		if (strncmp(ident_buf->model, "FX", 2) &&
846234949Sbapt		    strncmp(ident_buf->model, "NEC", 3) &&
847234949Sbapt		    strncmp(ident_buf->model, "Pioneer", 7) &&
848234949Sbapt		    strncmp(ident_buf->model, "SHARP", 5)) {
849234949Sbapt			ata_bswap(ident_buf->model, sizeof(ident_buf->model));
850234949Sbapt			ata_bswap(ident_buf->revision, sizeof(ident_buf->revision));
851234949Sbapt			ata_bswap(ident_buf->serial, sizeof(ident_buf->serial));
852234949Sbapt		}
853234949Sbapt		ata_btrim(ident_buf->model, sizeof(ident_buf->model));
854234949Sbapt		ata_bpack(ident_buf->model, ident_buf->model, sizeof(ident_buf->model));
855234949Sbapt		ata_btrim(ident_buf->revision, sizeof(ident_buf->revision));
856234949Sbapt		ata_bpack(ident_buf->revision, ident_buf->revision, sizeof(ident_buf->revision));
857234949Sbapt		ata_btrim(ident_buf->serial, sizeof(ident_buf->serial));
858234949Sbapt		ata_bpack(ident_buf->serial, ident_buf->serial, sizeof(ident_buf->serial));
859234949Sbapt		/* Device may need spin-up before IDENTIFY become valid. */
860234949Sbapt		if ((ident_buf->specconf == 0x37c8 ||
861234949Sbapt		     ident_buf->specconf == 0x738c) &&
862234949Sbapt		    ((ident_buf->config & ATA_RESP_INCOMPLETE) ||
863234949Sbapt		     softc->spinup == 0)) {
864234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SPINUP);
865234949Sbapt			xpt_release_ccb(done_ccb);
866234949Sbapt			xpt_schedule(periph, priority);
867234949Sbapt			return;
868234949Sbapt		}
869234949Sbapt		ident_buf = &path->device->ident_data;
870234949Sbapt		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
871234949Sbapt			/* Check that it is the same device. */
872234949Sbapt			if (bcmp(softc->ident_data.model, ident_buf->model,
873234949Sbapt			     sizeof(ident_buf->model)) ||
874234949Sbapt			    bcmp(softc->ident_data.revision, ident_buf->revision,
875234949Sbapt			     sizeof(ident_buf->revision)) ||
876234949Sbapt			    bcmp(softc->ident_data.serial, ident_buf->serial,
877234949Sbapt			     sizeof(ident_buf->serial))) {
878234949Sbapt				/* Device changed. */
879234949Sbapt				xpt_async(AC_LOST_DEVICE, path, NULL);
880234949Sbapt			} else {
881234949Sbapt				bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
882234949Sbapt				changed = 0;
883234949Sbapt			}
884234949Sbapt		}
885234949Sbapt		if (changed) {
886234949Sbapt			bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
887234949Sbapt			/* Clean up from previous instance of this device */
888234949Sbapt			if (path->device->serial_num != NULL) {
889234949Sbapt				free(path->device->serial_num, M_CAMXPT);
890234949Sbapt				path->device->serial_num = NULL;
891234949Sbapt				path->device->serial_num_len = 0;
892234949Sbapt			}
893234949Sbapt			if (path->device->device_id != NULL) {
894234949Sbapt				free(path->device->device_id, M_CAMXPT);
895234949Sbapt				path->device->device_id = NULL;
896234949Sbapt				path->device->device_id_len = 0;
897234949Sbapt			}
898234949Sbapt			path->device->serial_num =
899234949Sbapt				(u_int8_t *)malloc((sizeof(ident_buf->serial) + 1),
900234949Sbapt					   M_CAMXPT, M_NOWAIT);
901234949Sbapt			if (path->device->serial_num != NULL) {
902234949Sbapt				bcopy(ident_buf->serial,
903234949Sbapt				      path->device->serial_num,
904234949Sbapt				      sizeof(ident_buf->serial));
905234949Sbapt				path->device->serial_num[sizeof(ident_buf->serial)]
906234949Sbapt				    = '\0';
907234949Sbapt				path->device->serial_num_len =
908234949Sbapt				    strlen(path->device->serial_num);
909234949Sbapt			}
910234949Sbapt			if (ident_buf->enabled.extension &
911234949Sbapt			    ATA_SUPPORT_64BITWWN) {
912234949Sbapt				path->device->device_id =
913234949Sbapt				    malloc(16, M_CAMXPT, M_NOWAIT);
914234949Sbapt				if (path->device->device_id != NULL) {
915234949Sbapt					path->device->device_id_len = 16;
916234949Sbapt					bcopy(&fake_device_id_hdr,
917234949Sbapt					    path->device->device_id, 8);
918234949Sbapt					bcopy(ident_buf->wwn,
919234949Sbapt					    path->device->device_id + 8, 8);
920234949Sbapt				}
921234949Sbapt			}
922234949Sbapt
923234949Sbapt			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
924268899Sbapt			xpt_async(AC_GETDEV_CHANGED, path, NULL);
925268899Sbapt		}
926268899Sbapt		if (ident_buf->satacapabilities & ATA_SUPPORT_NCQ) {
927268899Sbapt			path->device->mintags = 2;
928268899Sbapt			path->device->maxtags =
929268899Sbapt			    ATA_QUEUE_LEN(ident_buf->queue) + 1;
930268899Sbapt		}
931268899Sbapt		ata_find_quirk(path->device);
932268899Sbapt		if (path->device->mintags != 0 &&
933272953Srodrigc		    path->bus->sim->max_tagged_dev_openings != 0) {
934251143Sbapt			/* Check if the SIM does not want queued commands. */
935251143Sbapt			bzero(&cpi, sizeof(cpi));
936251143Sbapt			xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
937251143Sbapt			cpi.ccb_h.func_code = XPT_PATH_INQ;
938251143Sbapt			xpt_action((union ccb *)&cpi);
939251143Sbapt			if (cpi.ccb_h.status == CAM_REQ_CMP &&
940251143Sbapt			    (cpi.hba_inquiry & PI_TAG_ABLE)) {
941251143Sbapt				/* Report SIM which tags are allowed. */
942251143Sbapt				bzero(&cts, sizeof(cts));
943272953Srodrigc				xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
944234949Sbapt				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
945234949Sbapt				cts.type = CTS_TYPE_CURRENT_SETTINGS;
946234949Sbapt				cts.xport_specific.sata.tags = path->device->maxtags;
947234949Sbapt				cts.xport_specific.sata.valid = CTS_SATA_VALID_TAGS;
948234949Sbapt				xpt_action((union ccb *)&cts);
949234949Sbapt			}
950234949Sbapt		}
951234949Sbapt		ata_device_transport(path);
952234949Sbapt		if (changed)
953234949Sbapt			proberequestdefaultnegotiation(periph);
954234949Sbapt		PROBE_SET_ACTION(softc, PROBE_SETMODE);
955234949Sbapt		xpt_release_ccb(done_ccb);
956234949Sbapt		xpt_schedule(periph, priority);
957234949Sbapt		return;
958234949Sbapt	}
959234949Sbapt	case PROBE_SPINUP:
960234949Sbapt		if (bootverbose)
961234949Sbapt			xpt_print(path, "Spin-up done\n");
962234949Sbapt		softc->spinup = 1;
963234949Sbapt		PROBE_SET_ACTION(softc, PROBE_IDENTIFY);
964234949Sbapt		xpt_release_ccb(done_ccb);
965234949Sbapt		xpt_schedule(periph, priority);
966234949Sbapt		return;
967234949Sbapt	case PROBE_SETMODE:
968234949Sbapt		if (path->device->transport != XPORT_SATA)
969234949Sbapt			goto notsata;
970234949Sbapt		/* Set supported bits. */
971234949Sbapt		bzero(&cts, sizeof(cts));
972234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
973234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
974234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
975234949Sbapt		xpt_action((union ccb *)&cts);
976234949Sbapt		if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
977234949Sbapt			caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H;
978234949Sbapt		else
979234949Sbapt			caps = 0;
980234949Sbapt		if (ident_buf->satacapabilities != 0xffff) {
981234949Sbapt			if (ident_buf->satacapabilities & ATA_SUPPORT_IFPWRMNGTRCV)
982234949Sbapt				caps |= CTS_SATA_CAPS_D_PMREQ;
983234949Sbapt			if (ident_buf->satacapabilities & ATA_SUPPORT_HAPST)
984234949Sbapt				caps |= CTS_SATA_CAPS_D_APST;
985234949Sbapt		}
986234949Sbapt		/* Mask unwanted bits. */
987234949Sbapt		bzero(&cts, sizeof(cts));
988234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
989234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
990234949Sbapt		cts.type = CTS_TYPE_USER_SETTINGS;
991234949Sbapt		xpt_action((union ccb *)&cts);
992234949Sbapt		if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
993234949Sbapt			caps &= cts.xport_specific.sata.caps;
994234949Sbapt		else
995234949Sbapt			caps = 0;
996234949Sbapt		/* Store result to SIM. */
997234949Sbapt		bzero(&cts, sizeof(cts));
998234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
999234949Sbapt		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1000234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
1001234949Sbapt		cts.xport_specific.sata.caps = caps;
1002234949Sbapt		cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS;
1003234949Sbapt		xpt_action((union ccb *)&cts);
1004234949Sbapt		softc->caps = caps;
1005234949Sbapt		if ((ident_buf->satasupport & ATA_SUPPORT_IFPWRMNGT) &&
1006234949Sbapt		    (!(softc->caps & CTS_SATA_CAPS_H_PMREQ)) !=
1007234949Sbapt		    (!(ident_buf->sataenabled & ATA_SUPPORT_IFPWRMNGT))) {
1008234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SETPM);
1009234949Sbapt			xpt_release_ccb(done_ccb);
1010234949Sbapt			xpt_schedule(periph, priority);
1011234949Sbapt			return;
1012234949Sbapt		}
1013234949Sbapt		/* FALLTHROUGH */
1014234949Sbapt	case PROBE_SETPM:
1015234949Sbapt		if (ident_buf->satacapabilities != 0xffff &&
1016234949Sbapt		    (ident_buf->satacapabilities & ATA_SUPPORT_DAPST) &&
1017234949Sbapt		    (!(softc->caps & CTS_SATA_CAPS_H_APST)) !=
1018234949Sbapt		    (!(ident_buf->sataenabled & ATA_ENABLED_DAPST))) {
1019234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SETAPST);
1020234949Sbapt			xpt_release_ccb(done_ccb);
1021234949Sbapt			xpt_schedule(periph, priority);
1022234949Sbapt			return;
1023234949Sbapt		}
1024234949Sbapt		/* FALLTHROUGH */
1025234949Sbapt	case PROBE_SETAPST:
1026234949Sbapt		if ((ident_buf->satasupport & ATA_SUPPORT_AUTOACTIVATE) &&
1027234949Sbapt		    (!(softc->caps & CTS_SATA_CAPS_H_DMAAA)) !=
1028234949Sbapt		    (!(ident_buf->sataenabled & ATA_SUPPORT_AUTOACTIVATE))) {
1029234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SETDMAAA);
1030234949Sbapt			xpt_release_ccb(done_ccb);
1031234949Sbapt			xpt_schedule(periph, priority);
1032234949Sbapt			return;
1033234949Sbapt		}
1034234949Sbapt		/* FALLTHROUGH */
1035234949Sbapt	case PROBE_SETDMAAA:
1036234949Sbapt		if ((ident_buf->satasupport & ATA_SUPPORT_ASYNCNOTIF) &&
1037234949Sbapt		    (!(softc->caps & CTS_SATA_CAPS_H_AN)) !=
1038234949Sbapt		    (!(ident_buf->sataenabled & ATA_SUPPORT_ASYNCNOTIF))) {
1039234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SETAN);
1040234949Sbapt			xpt_release_ccb(done_ccb);
1041234949Sbapt			xpt_schedule(periph, priority);
1042234949Sbapt			return;
1043234949Sbapt		}
1044234949Sbapt		/* FALLTHROUGH */
1045234949Sbapt	case PROBE_SETAN:
1046234949Sbaptnotsata:
1047234949Sbapt		if (path->device->protocol == PROTO_ATA) {
1048234949Sbapt			PROBE_SET_ACTION(softc, PROBE_SET_MULTI);
1049234949Sbapt		} else {
1050234949Sbapt			PROBE_SET_ACTION(softc, PROBE_INQUIRY);
1051234949Sbapt		}
1052234949Sbapt		xpt_release_ccb(done_ccb);
1053234949Sbapt		xpt_schedule(periph, priority);
1054234949Sbapt		return;
1055234949Sbapt	case PROBE_SET_MULTI:
1056234949Sbapt		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
1057234949Sbapt			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1058234949Sbapt			xpt_acquire_device(path->device);
1059234949Sbapt			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1060234949Sbapt			xpt_action(done_ccb);
1061234949Sbapt			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
1062234949Sbapt			    done_ccb);
1063234949Sbapt		}
1064234949Sbapt		PROBE_SET_ACTION(softc, PROBE_DONE);
1065234949Sbapt		break;
1066234949Sbapt	case PROBE_INQUIRY:
1067234949Sbapt	case PROBE_FULL_INQUIRY:
1068234949Sbapt	{
1069234949Sbapt		u_int8_t periph_qual, len;
1070234949Sbapt
1071234949Sbapt		path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
1072234949Sbapt
1073234949Sbapt		periph_qual = SID_QUAL(inq_buf);
1074234949Sbapt
1075234949Sbapt		if (periph_qual != SID_QUAL_LU_CONNECTED)
1076234949Sbapt			break;
1077234949Sbapt
1078234949Sbapt		/*
1079234949Sbapt		 * We conservatively request only
1080234949Sbapt		 * SHORT_INQUIRY_LEN bytes of inquiry
1081234949Sbapt		 * information during our first try
1082234949Sbapt		 * at sending an INQUIRY. If the device
1083234949Sbapt		 * has more information to give,
1084234949Sbapt		 * perform a second request specifying
1085234949Sbapt		 * the amount of information the device
1086234949Sbapt		 * is willing to give.
1087234949Sbapt		 */
1088272955Srodrigc		len = inq_buf->additional_length
1089234949Sbapt		    + offsetof(struct scsi_inquiry_data, additional_length) + 1;
1090234949Sbapt		if (softc->action == PROBE_INQUIRY
1091234949Sbapt		    && len > SHORT_INQUIRY_LENGTH) {
1092234949Sbapt			PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
1093234949Sbapt			xpt_release_ccb(done_ccb);
1094234949Sbapt			xpt_schedule(periph, priority);
1095234949Sbapt			return;
1096234949Sbapt		}
1097234949Sbapt
1098251143Sbapt		ata_device_transport(path);
1099234949Sbapt		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
1100234949Sbapt			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1101234949Sbapt			xpt_acquire_device(path->device);
1102234949Sbapt			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1103234949Sbapt			xpt_action(done_ccb);
1104234949Sbapt			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path, done_ccb);
1105234949Sbapt		}
1106234949Sbapt		PROBE_SET_ACTION(softc, PROBE_DONE);
1107234949Sbapt		break;
1108268899Sbapt	}
1109234949Sbapt	case PROBE_PM_PID:
1110234949Sbapt		if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) == 0)
1111234949Sbapt			bzero(ident_buf, sizeof(*ident_buf));
1112234949Sbapt		softc->pm_pid = (done_ccb->ataio.res.lba_high << 24) +
1113234949Sbapt		    (done_ccb->ataio.res.lba_mid << 16) +
1114234949Sbapt		    (done_ccb->ataio.res.lba_low << 8) +
1115234949Sbapt		    done_ccb->ataio.res.sector_count;
1116234949Sbapt		((uint32_t *)ident_buf)[0] = softc->pm_pid;
1117234949Sbapt		snprintf(ident_buf->model, sizeof(ident_buf->model),
1118234949Sbapt		    "Port Multiplier %08x", softc->pm_pid);
1119234949Sbapt		PROBE_SET_ACTION(softc, PROBE_PM_PRV);
1120234949Sbapt		xpt_release_ccb(done_ccb);
1121234949Sbapt		xpt_schedule(periph, priority);
1122234949Sbapt		return;
1123234949Sbapt	case PROBE_PM_PRV:
1124234949Sbapt		softc->pm_prv = (done_ccb->ataio.res.lba_high << 24) +
1125234949Sbapt		    (done_ccb->ataio.res.lba_mid << 16) +
1126234949Sbapt		    (done_ccb->ataio.res.lba_low << 8) +
1127234949Sbapt		    done_ccb->ataio.res.sector_count;
1128234949Sbapt		((uint32_t *)ident_buf)[1] = softc->pm_prv;
1129234949Sbapt		snprintf(ident_buf->revision, sizeof(ident_buf->revision),
1130234949Sbapt		    "%04x", softc->pm_prv);
1131234949Sbapt		path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
1132234949Sbapt		ata_device_transport(path);
1133234949Sbapt		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED)
1134234949Sbapt			proberequestdefaultnegotiation(periph);
1135234949Sbapt		/* Set supported bits. */
1136234949Sbapt		bzero(&cts, sizeof(cts));
1137234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
1138234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1139272955Srodrigc		cts.type = CTS_TYPE_CURRENT_SETTINGS;
1140272955Srodrigc		xpt_action((union ccb *)&cts);
1141272955Srodrigc		if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
1142234949Sbapt			caps = cts.xport_specific.sata.caps & CTS_SATA_CAPS_H;
1143234949Sbapt		else
1144234949Sbapt			caps = 0;
1145234949Sbapt		/* All PMPs must support PM requests. */
1146234949Sbapt		caps |= CTS_SATA_CAPS_D_PMREQ;
1147234949Sbapt		/* Mask unwanted bits. */
1148234949Sbapt		bzero(&cts, sizeof(cts));
1149234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
1150234949Sbapt		cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1151234949Sbapt		cts.type = CTS_TYPE_USER_SETTINGS;
1152234949Sbapt		xpt_action((union ccb *)&cts);
1153234949Sbapt		if (cts.xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
1154234949Sbapt			caps &= cts.xport_specific.sata.caps;
1155234949Sbapt		else
1156234949Sbapt			caps = 0;
1157234949Sbapt		/* Store result to SIM. */
1158234949Sbapt		bzero(&cts, sizeof(cts));
1159234949Sbapt		xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
1160234949Sbapt		cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1161234949Sbapt		cts.type = CTS_TYPE_CURRENT_SETTINGS;
1162234949Sbapt		cts.xport_specific.sata.caps = caps;
1163234949Sbapt		cts.xport_specific.sata.valid = CTS_SATA_VALID_CAPS;
1164234949Sbapt		xpt_action((union ccb *)&cts);
1165234949Sbapt		softc->caps = caps;
1166234949Sbapt		/* Remember what transport thinks about AEN. */
1167234949Sbapt		if (softc->caps & CTS_SATA_CAPS_H_AN)
1168234949Sbapt			path->device->inq_flags |= SID_AEN;
1169268899Sbapt		else
1170234949Sbapt			path->device->inq_flags &= ~SID_AEN;
1171272955Srodrigc		xpt_async(AC_GETDEV_CHANGED, path, NULL);
1172272955Srodrigc		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
1173272955Srodrigc			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1174272955Srodrigc			xpt_acquire_device(path->device);
1175234949Sbapt			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1176234949Sbapt			xpt_action(done_ccb);
1177234949Sbapt			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
1178234949Sbapt			    done_ccb);
1179234949Sbapt		} else {
1180234949Sbapt			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1181234949Sbapt			xpt_action(done_ccb);
1182272955Srodrigc			xpt_async(AC_SCSI_AEN, done_ccb->ccb_h.path, done_ccb);
1183234949Sbapt		}
1184234949Sbapt		PROBE_SET_ACTION(softc, PROBE_DONE);
1185234949Sbapt		break;
1186234949Sbapt	case PROBE_IDENTIFY_SES:
1187234949Sbapt	case PROBE_IDENTIFY_SAFTE:
1188234949Sbapt		if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
1189234949Sbapt			/* Check that it is the same device. */
1190234949Sbapt			if (bcmp(&softc->ident_data, ident_buf, 53)) {
1191234949Sbapt				/* Device changed. */
1192234949Sbapt				xpt_async(AC_LOST_DEVICE, path, NULL);
1193234949Sbapt			} else {
1194234949Sbapt				bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
1195234949Sbapt				changed = 0;
1196234949Sbapt			}
1197234949Sbapt		}
1198234949Sbapt		if (changed) {
1199234949Sbapt			bcopy(&softc->ident_data, ident_buf, sizeof(struct ata_params));
1200234949Sbapt			/* Clean up from previous instance of this device */
1201234949Sbapt			if (path->device->device_id != NULL) {
1202234949Sbapt				free(path->device->device_id, M_CAMXPT);
1203234949Sbapt				path->device->device_id = NULL;
1204234949Sbapt				path->device->device_id_len = 0;
1205234949Sbapt			}
1206234949Sbapt			path->device->device_id =
1207234949Sbapt			    malloc(16, M_CAMXPT, M_NOWAIT);
1208234949Sbapt			if (path->device->device_id != NULL) {
1209234949Sbapt				path->device->device_id_len = 16;
1210234949Sbapt				bcopy(&fake_device_id_hdr,
1211234949Sbapt				    path->device->device_id, 8);
1212234949Sbapt				bcopy(((uint8_t*)ident_buf) + 2,
1213234949Sbapt				    path->device->device_id + 8, 8);
1214			}
1215
1216			path->device->flags |= CAM_DEV_IDENTIFY_DATA_VALID;
1217		}
1218		ata_device_transport(path);
1219		if (changed)
1220			proberequestdefaultnegotiation(periph);
1221
1222		if (periph->path->device->flags & CAM_DEV_UNCONFIGURED) {
1223			path->device->flags &= ~CAM_DEV_UNCONFIGURED;
1224			xpt_acquire_device(path->device);
1225			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
1226			xpt_action(done_ccb);
1227			xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
1228			    done_ccb);
1229		}
1230		PROBE_SET_ACTION(softc, PROBE_DONE);
1231		break;
1232	default:
1233		panic("probedone: invalid action state 0x%x\n", softc->action);
1234	}
1235done:
1236	if (softc->restart) {
1237		softc->restart = 0;
1238		xpt_release_ccb(done_ccb);
1239		probeschedule(periph);
1240		return;
1241	}
1242	xpt_release_ccb(done_ccb);
1243	CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
1244	while ((done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs))) {
1245		TAILQ_REMOVE(&softc->request_ccbs,
1246		    &done_ccb->ccb_h, periph_links.tqe);
1247		done_ccb->ccb_h.status = found ? CAM_REQ_CMP : CAM_REQ_CMP_ERR;
1248		xpt_done(done_ccb);
1249	}
1250	cam_periph_invalidate(periph);
1251	cam_release_devq(periph->path,
1252	    RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_XPT + 1, FALSE);
1253	cam_periph_release_locked(periph);
1254}
1255
1256static void
1257probecleanup(struct cam_periph *periph)
1258{
1259	free(periph->softc, M_CAMXPT);
1260}
1261
1262static void
1263ata_find_quirk(struct cam_ed *device)
1264{
1265	struct ata_quirk_entry *quirk;
1266	caddr_t	match;
1267
1268	match = cam_quirkmatch((caddr_t)&device->ident_data,
1269			       (caddr_t)ata_quirk_table,
1270			       ata_quirk_table_size,
1271			       sizeof(*ata_quirk_table), ata_identify_match);
1272
1273	if (match == NULL)
1274		panic("xpt_find_quirk: device didn't match wildcard entry!!");
1275
1276	quirk = (struct ata_quirk_entry *)match;
1277	device->quirk = quirk;
1278	if (quirk->quirks & CAM_QUIRK_MAXTAGS) {
1279		device->mintags = quirk->mintags;
1280		device->maxtags = quirk->maxtags;
1281	}
1282}
1283
1284typedef struct {
1285	union	ccb *request_ccb;
1286	struct 	ccb_pathinq *cpi;
1287	int	counter;
1288} ata_scan_bus_info;
1289
1290/*
1291 * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
1292 * As the scan progresses, xpt_scan_bus is used as the
1293 * callback on completion function.
1294 */
1295static void
1296ata_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
1297{
1298	struct	cam_path *path;
1299	ata_scan_bus_info *scan_info;
1300	union	ccb *work_ccb, *reset_ccb;
1301	cam_status status;
1302
1303	CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
1304		  ("xpt_scan_bus\n"));
1305	switch (request_ccb->ccb_h.func_code) {
1306	case XPT_SCAN_BUS:
1307	case XPT_SCAN_TGT:
1308		/* Find out the characteristics of the bus */
1309		work_ccb = xpt_alloc_ccb_nowait();
1310		if (work_ccb == NULL) {
1311			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1312			xpt_done(request_ccb);
1313			return;
1314		}
1315		xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
1316			      request_ccb->ccb_h.pinfo.priority);
1317		work_ccb->ccb_h.func_code = XPT_PATH_INQ;
1318		xpt_action(work_ccb);
1319		if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
1320			request_ccb->ccb_h.status = work_ccb->ccb_h.status;
1321			xpt_free_ccb(work_ccb);
1322			xpt_done(request_ccb);
1323			return;
1324		}
1325
1326		/* We may need to reset bus first, if we haven't done it yet. */
1327		if ((work_ccb->cpi.hba_inquiry &
1328		    (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) &&
1329		    !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) &&
1330		    !timevalisset(&request_ccb->ccb_h.path->bus->last_reset)) {
1331			reset_ccb = xpt_alloc_ccb_nowait();
1332			if (reset_ccb == NULL) {
1333				request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1334				xpt_free_ccb(work_ccb);
1335				xpt_done(request_ccb);
1336				return;
1337			}
1338			xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path,
1339			      CAM_PRIORITY_NONE);
1340			reset_ccb->ccb_h.func_code = XPT_RESET_BUS;
1341			xpt_action(reset_ccb);
1342			if (reset_ccb->ccb_h.status != CAM_REQ_CMP) {
1343				request_ccb->ccb_h.status = reset_ccb->ccb_h.status;
1344				xpt_free_ccb(reset_ccb);
1345				xpt_free_ccb(work_ccb);
1346				xpt_done(request_ccb);
1347				return;
1348			}
1349			xpt_free_ccb(reset_ccb);
1350		}
1351
1352		/* Save some state for use while we probe for devices */
1353		scan_info = (ata_scan_bus_info *)
1354		    malloc(sizeof(ata_scan_bus_info), M_CAMXPT, M_NOWAIT);
1355		if (scan_info == NULL) {
1356			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1357			xpt_free_ccb(work_ccb);
1358			xpt_done(request_ccb);
1359			return;
1360		}
1361		scan_info->request_ccb = request_ccb;
1362		scan_info->cpi = &work_ccb->cpi;
1363		/* If PM supported, probe it first. */
1364		if (scan_info->cpi->hba_inquiry & PI_SATAPM)
1365			scan_info->counter = scan_info->cpi->max_target;
1366		else
1367			scan_info->counter = 0;
1368
1369		work_ccb = xpt_alloc_ccb_nowait();
1370		if (work_ccb == NULL) {
1371			free(scan_info, M_CAMXPT);
1372			request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1373			xpt_done(request_ccb);
1374			break;
1375		}
1376		goto scan_next;
1377	case XPT_SCAN_LUN:
1378		work_ccb = request_ccb;
1379		/* Reuse the same CCB to query if a device was really found */
1380		scan_info = (ata_scan_bus_info *)work_ccb->ccb_h.ppriv_ptr0;
1381		/* If there is PMP... */
1382		if ((scan_info->cpi->hba_inquiry & PI_SATAPM) &&
1383		    (scan_info->counter == scan_info->cpi->max_target)) {
1384			if (work_ccb->ccb_h.status == CAM_REQ_CMP) {
1385				/* everything else will be probed by it */
1386				/* Free the current request path- we're done with it. */
1387				xpt_free_path(work_ccb->ccb_h.path);
1388				goto done;
1389			} else {
1390				struct ccb_trans_settings cts;
1391
1392				/* Report SIM that PM is absent. */
1393				bzero(&cts, sizeof(cts));
1394				xpt_setup_ccb(&cts.ccb_h,
1395				    work_ccb->ccb_h.path, CAM_PRIORITY_NONE);
1396				cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1397				cts.type = CTS_TYPE_CURRENT_SETTINGS;
1398				cts.xport_specific.sata.pm_present = 0;
1399				cts.xport_specific.sata.valid = CTS_SATA_VALID_PM;
1400				xpt_action((union ccb *)&cts);
1401			}
1402		}
1403		/* Free the current request path- we're done with it. */
1404		xpt_free_path(work_ccb->ccb_h.path);
1405		if (scan_info->counter ==
1406		    ((scan_info->cpi->hba_inquiry & PI_SATAPM) ?
1407		    0 : scan_info->cpi->max_target)) {
1408done:
1409			xpt_free_ccb(work_ccb);
1410			xpt_free_ccb((union ccb *)scan_info->cpi);
1411			request_ccb = scan_info->request_ccb;
1412			free(scan_info, M_CAMXPT);
1413			request_ccb->ccb_h.status = CAM_REQ_CMP;
1414			xpt_done(request_ccb);
1415			break;
1416		}
1417		/* Take next device. Wrap from max (PMP) to 0. */
1418		scan_info->counter = (scan_info->counter + 1 ) %
1419		    (scan_info->cpi->max_target + 1);
1420scan_next:
1421		status = xpt_create_path(&path, xpt_periph,
1422		    scan_info->request_ccb->ccb_h.path_id,
1423		    scan_info->counter, 0);
1424		if (status != CAM_REQ_CMP) {
1425			printf("xpt_scan_bus: xpt_create_path failed"
1426			    " with status %#x, bus scan halted\n",
1427			    status);
1428			xpt_free_ccb(work_ccb);
1429			xpt_free_ccb((union ccb *)scan_info->cpi);
1430			request_ccb = scan_info->request_ccb;
1431			free(scan_info, M_CAMXPT);
1432			request_ccb->ccb_h.status = status;
1433			xpt_done(request_ccb);
1434			break;
1435		}
1436		xpt_setup_ccb(&work_ccb->ccb_h, path,
1437		    scan_info->request_ccb->ccb_h.pinfo.priority);
1438		work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1439		work_ccb->ccb_h.cbfcnp = ata_scan_bus;
1440		work_ccb->ccb_h.ppriv_ptr0 = scan_info;
1441		work_ccb->crcn.flags = scan_info->request_ccb->crcn.flags;
1442		xpt_action(work_ccb);
1443		break;
1444	default:
1445		break;
1446	}
1447}
1448
1449static void
1450ata_scan_lun(struct cam_periph *periph, struct cam_path *path,
1451	     cam_flags flags, union ccb *request_ccb)
1452{
1453	struct ccb_pathinq cpi;
1454	cam_status status;
1455	struct cam_path *new_path;
1456	struct cam_periph *old_periph;
1457
1458	CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_scan_lun\n"));
1459
1460	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
1461	cpi.ccb_h.func_code = XPT_PATH_INQ;
1462	xpt_action((union ccb *)&cpi);
1463
1464	if (cpi.ccb_h.status != CAM_REQ_CMP) {
1465		if (request_ccb != NULL) {
1466			request_ccb->ccb_h.status = cpi.ccb_h.status;
1467			xpt_done(request_ccb);
1468		}
1469		return;
1470	}
1471
1472	if (request_ccb == NULL) {
1473		request_ccb = xpt_alloc_ccb_nowait();
1474		if (request_ccb == NULL) {
1475			xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
1476			    "can't continue\n");
1477			return;
1478		}
1479		status = xpt_create_path(&new_path, xpt_periph,
1480					  path->bus->path_id,
1481					  path->target->target_id,
1482					  path->device->lun_id);
1483		if (status != CAM_REQ_CMP) {
1484			xpt_print(path, "xpt_scan_lun: can't create path, "
1485			    "can't continue\n");
1486			xpt_free_ccb(request_ccb);
1487			return;
1488		}
1489		xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT);
1490		request_ccb->ccb_h.cbfcnp = xptscandone;
1491		request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
1492		request_ccb->crcn.flags = flags;
1493	}
1494
1495	if ((old_periph = cam_periph_find(path, "aprobe")) != NULL) {
1496		if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
1497			probe_softc *softc;
1498
1499			softc = (probe_softc *)old_periph->softc;
1500			TAILQ_INSERT_TAIL(&softc->request_ccbs,
1501				&request_ccb->ccb_h, periph_links.tqe);
1502			softc->restart = 1;
1503		} else {
1504			request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
1505			xpt_done(request_ccb);
1506		}
1507	} else {
1508		status = cam_periph_alloc(proberegister, NULL, probecleanup,
1509					  probestart, "aprobe",
1510					  CAM_PERIPH_BIO,
1511					  request_ccb->ccb_h.path, NULL, 0,
1512					  request_ccb);
1513
1514		if (status != CAM_REQ_CMP) {
1515			xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
1516			    "returned an error, can't continue probe\n");
1517			request_ccb->ccb_h.status = status;
1518			xpt_done(request_ccb);
1519		}
1520	}
1521}
1522
1523static void
1524xptscandone(struct cam_periph *periph, union ccb *done_ccb)
1525{
1526
1527	xpt_free_path(done_ccb->ccb_h.path);
1528	xpt_free_ccb(done_ccb);
1529}
1530
1531static struct cam_ed *
1532ata_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
1533{
1534	struct cam_path path;
1535	struct ata_quirk_entry *quirk;
1536	struct cam_ed *device;
1537	struct cam_ed *cur_device;
1538
1539	device = xpt_alloc_device(bus, target, lun_id);
1540	if (device == NULL)
1541		return (NULL);
1542
1543	/*
1544	 * Take the default quirk entry until we have inquiry
1545	 * data and can determine a better quirk to use.
1546	 */
1547	quirk = &ata_quirk_table[ata_quirk_table_size - 1];
1548	device->quirk = (void *)quirk;
1549	device->mintags = 0;
1550	device->maxtags = 0;
1551	bzero(&device->inq_data, sizeof(device->inq_data));
1552	device->inq_flags = 0;
1553	device->queue_flags = 0;
1554	device->serial_num = NULL;
1555	device->serial_num_len = 0;
1556
1557	/*
1558	 * XXX should be limited by number of CCBs this bus can
1559	 * do.
1560	 */
1561	bus->sim->max_ccbs += device->ccbq.devq_openings;
1562	/* Insertion sort into our target's device list */
1563	cur_device = TAILQ_FIRST(&target->ed_entries);
1564	while (cur_device != NULL && cur_device->lun_id < lun_id)
1565		cur_device = TAILQ_NEXT(cur_device, links);
1566	if (cur_device != NULL) {
1567		TAILQ_INSERT_BEFORE(cur_device, device, links);
1568	} else {
1569		TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
1570	}
1571	target->generation++;
1572	if (lun_id != CAM_LUN_WILDCARD) {
1573		xpt_compile_path(&path,
1574				 NULL,
1575				 bus->path_id,
1576				 target->target_id,
1577				 lun_id);
1578		ata_device_transport(&path);
1579		xpt_release_path(&path);
1580	}
1581
1582	return (device);
1583}
1584
1585static void
1586ata_device_transport(struct cam_path *path)
1587{
1588	struct ccb_pathinq cpi;
1589	struct ccb_trans_settings cts;
1590	struct scsi_inquiry_data *inq_buf = NULL;
1591	struct ata_params *ident_buf = NULL;
1592
1593	/* Get transport information from the SIM */
1594	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
1595	cpi.ccb_h.func_code = XPT_PATH_INQ;
1596	xpt_action((union ccb *)&cpi);
1597
1598	path->device->transport = cpi.transport;
1599	if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
1600		inq_buf = &path->device->inq_data;
1601	if ((path->device->flags & CAM_DEV_IDENTIFY_DATA_VALID) != 0)
1602		ident_buf = &path->device->ident_data;
1603	if (path->device->protocol == PROTO_ATA) {
1604		path->device->protocol_version = ident_buf ?
1605		    ata_version(ident_buf->version_major) : cpi.protocol_version;
1606	} else if (path->device->protocol == PROTO_SCSI) {
1607		path->device->protocol_version = inq_buf ?
1608		    SID_ANSI_REV(inq_buf) : cpi.protocol_version;
1609	}
1610	path->device->transport_version = ident_buf ?
1611	    ata_version(ident_buf->version_major) : cpi.transport_version;
1612
1613	/* Tell the controller what we think */
1614	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
1615	cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
1616	cts.type = CTS_TYPE_CURRENT_SETTINGS;
1617	cts.transport = path->device->transport;
1618	cts.transport_version = path->device->transport_version;
1619	cts.protocol = path->device->protocol;
1620	cts.protocol_version = path->device->protocol_version;
1621	cts.proto_specific.valid = 0;
1622	if (ident_buf) {
1623		if (path->device->transport == XPORT_ATA) {
1624			cts.xport_specific.ata.atapi =
1625			    (ident_buf->config == ATA_PROTO_CFA) ? 0 :
1626			    ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 :
1627			    ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0;
1628			cts.xport_specific.ata.valid = CTS_ATA_VALID_ATAPI;
1629		} else {
1630			cts.xport_specific.sata.atapi =
1631			    (ident_buf->config == ATA_PROTO_CFA) ? 0 :
1632			    ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_16) ? 16 :
1633			    ((ident_buf->config & ATA_PROTO_MASK) == ATA_PROTO_ATAPI_12) ? 12 : 0;
1634			cts.xport_specific.sata.valid = CTS_SATA_VALID_ATAPI;
1635		}
1636	} else
1637		cts.xport_specific.valid = 0;
1638	xpt_action((union ccb *)&cts);
1639}
1640
1641static void
1642ata_dev_advinfo(union ccb *start_ccb)
1643{
1644	struct cam_ed *device;
1645	struct ccb_dev_advinfo *cdai;
1646	off_t amt;
1647
1648	start_ccb->ccb_h.status = CAM_REQ_INVALID;
1649	device = start_ccb->ccb_h.path->device;
1650	cdai = &start_ccb->cdai;
1651	switch(cdai->buftype) {
1652	case CDAI_TYPE_SCSI_DEVID:
1653		if (cdai->flags & CDAI_FLAG_STORE)
1654			return;
1655		cdai->provsiz = device->device_id_len;
1656		if (device->device_id_len == 0)
1657			break;
1658		amt = device->device_id_len;
1659		if (cdai->provsiz > cdai->bufsiz)
1660			amt = cdai->bufsiz;
1661		memcpy(cdai->buf, device->device_id, amt);
1662		break;
1663	case CDAI_TYPE_SERIAL_NUM:
1664		if (cdai->flags & CDAI_FLAG_STORE)
1665			return;
1666		cdai->provsiz = device->serial_num_len;
1667		if (device->serial_num_len == 0)
1668			break;
1669		amt = device->serial_num_len;
1670		if (cdai->provsiz > cdai->bufsiz)
1671			amt = cdai->bufsiz;
1672		memcpy(cdai->buf, device->serial_num, amt);
1673		break;
1674	case CDAI_TYPE_PHYS_PATH:
1675		if (cdai->flags & CDAI_FLAG_STORE) {
1676			if (device->physpath != NULL)
1677				free(device->physpath, M_CAMXPT);
1678			device->physpath_len = cdai->bufsiz;
1679			/* Clear existing buffer if zero length */
1680			if (cdai->bufsiz == 0)
1681				break;
1682			device->physpath = malloc(cdai->bufsiz, M_CAMXPT, M_NOWAIT);
1683			if (device->physpath == NULL) {
1684				start_ccb->ccb_h.status = CAM_REQ_ABORTED;
1685				return;
1686			}
1687			memcpy(device->physpath, cdai->buf, cdai->bufsiz);
1688		} else {
1689			cdai->provsiz = device->physpath_len;
1690			if (device->physpath_len == 0)
1691				break;
1692			amt = device->physpath_len;
1693			if (cdai->provsiz > cdai->bufsiz)
1694				amt = cdai->bufsiz;
1695			memcpy(cdai->buf, device->physpath, amt);
1696		}
1697		break;
1698	default:
1699		return;
1700	}
1701	start_ccb->ccb_h.status = CAM_REQ_CMP;
1702
1703	if (cdai->flags & CDAI_FLAG_STORE) {
1704		int owned;
1705
1706		owned = mtx_owned(start_ccb->ccb_h.path->bus->sim->mtx);
1707		if (owned == 0)
1708			mtx_lock(start_ccb->ccb_h.path->bus->sim->mtx);
1709		xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path,
1710			  (void *)(uintptr_t)cdai->buftype);
1711		if (owned == 0)
1712			mtx_unlock(start_ccb->ccb_h.path->bus->sim->mtx);
1713	}
1714}
1715
1716static void
1717ata_action(union ccb *start_ccb)
1718{
1719
1720	switch (start_ccb->ccb_h.func_code) {
1721	case XPT_SET_TRAN_SETTINGS:
1722	{
1723		ata_set_transfer_settings(&start_ccb->cts,
1724					   start_ccb->ccb_h.path->device,
1725					   /*async_update*/FALSE);
1726		break;
1727	}
1728	case XPT_SCAN_BUS:
1729	case XPT_SCAN_TGT:
1730		ata_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
1731		break;
1732	case XPT_SCAN_LUN:
1733		ata_scan_lun(start_ccb->ccb_h.path->periph,
1734			      start_ccb->ccb_h.path, start_ccb->crcn.flags,
1735			      start_ccb);
1736		break;
1737	case XPT_GET_TRAN_SETTINGS:
1738	{
1739		ata_get_transfer_settings(&start_ccb->cts);
1740		break;
1741	}
1742	case XPT_SCSI_IO:
1743	{
1744		struct cam_ed *device;
1745		u_int	maxlen = 0;
1746
1747		device = start_ccb->ccb_h.path->device;
1748		if (device->protocol == PROTO_SCSI &&
1749		    (device->flags & CAM_DEV_IDENTIFY_DATA_VALID)) {
1750			uint16_t p =
1751			    device->ident_data.config & ATA_PROTO_MASK;
1752
1753			maxlen =
1754			    (device->ident_data.config == ATA_PROTO_CFA) ? 0 :
1755			    (p == ATA_PROTO_ATAPI_16) ? 16 :
1756			    (p == ATA_PROTO_ATAPI_12) ? 12 : 0;
1757		}
1758		if (start_ccb->csio.cdb_len > maxlen) {
1759			start_ccb->ccb_h.status = CAM_REQ_INVALID;
1760			xpt_done(start_ccb);
1761			break;
1762		}
1763		xpt_action_default(start_ccb);
1764		break;
1765	}
1766	case XPT_DEV_ADVINFO:
1767	{
1768		ata_dev_advinfo(start_ccb);
1769		break;
1770	}
1771	default:
1772		xpt_action_default(start_ccb);
1773		break;
1774	}
1775}
1776
1777static void
1778ata_get_transfer_settings(struct ccb_trans_settings *cts)
1779{
1780	struct	ccb_trans_settings_ata *ata;
1781	struct	ccb_trans_settings_scsi *scsi;
1782	struct	cam_ed *device;
1783	struct	cam_sim *sim;
1784
1785	device = cts->ccb_h.path->device;
1786	sim = cts->ccb_h.path->bus->sim;
1787	(*(sim->sim_action))(sim, (union ccb *)cts);
1788
1789	if (cts->protocol == PROTO_UNKNOWN ||
1790	    cts->protocol == PROTO_UNSPECIFIED) {
1791		cts->protocol = device->protocol;
1792		cts->protocol_version = device->protocol_version;
1793	}
1794
1795	if (cts->protocol == PROTO_ATA) {
1796		ata = &cts->proto_specific.ata;
1797		if ((ata->valid & CTS_ATA_VALID_TQ) == 0) {
1798			ata->valid |= CTS_ATA_VALID_TQ;
1799			if (cts->type == CTS_TYPE_USER_SETTINGS ||
1800			    (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
1801			    (device->inq_flags & SID_CmdQue) != 0)
1802				ata->flags |= CTS_ATA_FLAGS_TAG_ENB;
1803		}
1804	}
1805	if (cts->protocol == PROTO_SCSI) {
1806		scsi = &cts->proto_specific.scsi;
1807		if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
1808			scsi->valid |= CTS_SCSI_VALID_TQ;
1809			if (cts->type == CTS_TYPE_USER_SETTINGS ||
1810			    (device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
1811			    (device->inq_flags & SID_CmdQue) != 0)
1812				scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB;
1813		}
1814	}
1815
1816	if (cts->transport == XPORT_UNKNOWN ||
1817	    cts->transport == XPORT_UNSPECIFIED) {
1818		cts->transport = device->transport;
1819		cts->transport_version = device->transport_version;
1820	}
1821}
1822
1823static void
1824ata_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
1825			   int async_update)
1826{
1827	struct	ccb_pathinq cpi;
1828	struct	ccb_trans_settings_ata *ata;
1829	struct	ccb_trans_settings_scsi *scsi;
1830	struct	cam_sim *sim;
1831	struct	ata_params *ident_data;
1832	struct	scsi_inquiry_data *inq_data;
1833
1834	if (device == NULL) {
1835		cts->ccb_h.status = CAM_PATH_INVALID;
1836		xpt_done((union ccb *)cts);
1837		return;
1838	}
1839
1840	if (cts->protocol == PROTO_UNKNOWN
1841	 || cts->protocol == PROTO_UNSPECIFIED) {
1842		cts->protocol = device->protocol;
1843		cts->protocol_version = device->protocol_version;
1844	}
1845
1846	if (cts->protocol_version == PROTO_VERSION_UNKNOWN
1847	 || cts->protocol_version == PROTO_VERSION_UNSPECIFIED)
1848		cts->protocol_version = device->protocol_version;
1849
1850	if (cts->protocol != device->protocol) {
1851		xpt_print(cts->ccb_h.path, "Uninitialized Protocol %x:%x?\n",
1852		       cts->protocol, device->protocol);
1853		cts->protocol = device->protocol;
1854	}
1855
1856	if (cts->protocol_version > device->protocol_version) {
1857		if (bootverbose) {
1858			xpt_print(cts->ccb_h.path, "Down reving Protocol "
1859			    "Version from %d to %d?\n", cts->protocol_version,
1860			    device->protocol_version);
1861		}
1862		cts->protocol_version = device->protocol_version;
1863	}
1864
1865	if (cts->transport == XPORT_UNKNOWN
1866	 || cts->transport == XPORT_UNSPECIFIED) {
1867		cts->transport = device->transport;
1868		cts->transport_version = device->transport_version;
1869	}
1870
1871	if (cts->transport_version == XPORT_VERSION_UNKNOWN
1872	 || cts->transport_version == XPORT_VERSION_UNSPECIFIED)
1873		cts->transport_version = device->transport_version;
1874
1875	if (cts->transport != device->transport) {
1876		xpt_print(cts->ccb_h.path, "Uninitialized Transport %x:%x?\n",
1877		    cts->transport, device->transport);
1878		cts->transport = device->transport;
1879	}
1880
1881	if (cts->transport_version > device->transport_version) {
1882		if (bootverbose) {
1883			xpt_print(cts->ccb_h.path, "Down reving Transport "
1884			    "Version from %d to %d?\n", cts->transport_version,
1885			    device->transport_version);
1886		}
1887		cts->transport_version = device->transport_version;
1888	}
1889
1890	sim = cts->ccb_h.path->bus->sim;
1891	ident_data = &device->ident_data;
1892	inq_data = &device->inq_data;
1893	if (cts->protocol == PROTO_ATA)
1894		ata = &cts->proto_specific.ata;
1895	else
1896		ata = NULL;
1897	if (cts->protocol == PROTO_SCSI)
1898		scsi = &cts->proto_specific.scsi;
1899	else
1900		scsi = NULL;
1901	xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, CAM_PRIORITY_NONE);
1902	cpi.ccb_h.func_code = XPT_PATH_INQ;
1903	xpt_action((union ccb *)&cpi);
1904
1905	/* Sanity checking */
1906	if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
1907	 || (ata && (ident_data->satacapabilities & ATA_SUPPORT_NCQ) == 0)
1908	 || (scsi && (INQ_DATA_TQ_ENABLED(inq_data)) == 0)
1909	 || (device->queue_flags & SCP_QUEUE_DQUE) != 0
1910	 || (device->mintags == 0)) {
1911		/*
1912		 * Can't tag on hardware that doesn't support tags,
1913		 * doesn't have it enabled, or has broken tag support.
1914		 */
1915		if (ata)
1916			ata->flags &= ~CTS_ATA_FLAGS_TAG_ENB;
1917		if (scsi)
1918			scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
1919	}
1920
1921	/* Start/stop tags use. */
1922	if (cts->type == CTS_TYPE_CURRENT_SETTINGS &&
1923	    ((ata && (ata->valid & CTS_ATA_VALID_TQ) != 0) ||
1924	     (scsi && (scsi->valid & CTS_SCSI_VALID_TQ) != 0))) {
1925		int nowt, newt = 0;
1926
1927		nowt = ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0 ||
1928			(device->inq_flags & SID_CmdQue) != 0);
1929		if (ata)
1930			newt = (ata->flags & CTS_ATA_FLAGS_TAG_ENB) != 0;
1931		if (scsi)
1932			newt = (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0;
1933
1934		if (newt && !nowt) {
1935			/*
1936			 * Delay change to use tags until after a
1937			 * few commands have gone to this device so
1938			 * the controller has time to perform transfer
1939			 * negotiations without tagged messages getting
1940			 * in the way.
1941			 */
1942			device->tag_delay_count = CAM_TAG_DELAY_COUNT;
1943			device->flags |= CAM_DEV_TAG_AFTER_COUNT;
1944		} else if (nowt && !newt)
1945			xpt_stop_tags(cts->ccb_h.path);
1946	}
1947
1948	if (async_update == FALSE)
1949		(*(sim->sim_action))(sim, (union ccb *)cts);
1950}
1951
1952/*
1953 * Handle any per-device event notifications that require action by the XPT.
1954 */
1955static void
1956ata_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
1957	      struct cam_ed *device, void *async_arg)
1958{
1959	cam_status status;
1960	struct cam_path newpath;
1961
1962	/*
1963	 * We only need to handle events for real devices.
1964	 */
1965	if (target->target_id == CAM_TARGET_WILDCARD
1966	 || device->lun_id == CAM_LUN_WILDCARD)
1967		return;
1968
1969	/*
1970	 * We need our own path with wildcards expanded to
1971	 * handle certain types of events.
1972	 */
1973	if ((async_code == AC_SENT_BDR)
1974	 || (async_code == AC_BUS_RESET)
1975	 || (async_code == AC_INQ_CHANGED))
1976		status = xpt_compile_path(&newpath, NULL,
1977					  bus->path_id,
1978					  target->target_id,
1979					  device->lun_id);
1980	else
1981		status = CAM_REQ_CMP_ERR;
1982
1983	if (status == CAM_REQ_CMP) {
1984		if (async_code == AC_INQ_CHANGED) {
1985			/*
1986			 * We've sent a start unit command, or
1987			 * something similar to a device that
1988			 * may have caused its inquiry data to
1989			 * change. So we re-scan the device to
1990			 * refresh the inquiry data for it.
1991			 */
1992			ata_scan_lun(newpath.periph, &newpath,
1993				     CAM_EXPECT_INQ_CHANGE, NULL);
1994		} else {
1995			/* We need to reinitialize device after reset. */
1996			ata_scan_lun(newpath.periph, &newpath,
1997				     0, NULL);
1998		}
1999		xpt_release_path(&newpath);
2000	} else if (async_code == AC_LOST_DEVICE &&
2001	    (device->flags & CAM_DEV_UNCONFIGURED) == 0) {
2002		device->flags |= CAM_DEV_UNCONFIGURED;
2003		xpt_release_device(device);
2004	} else if (async_code == AC_TRANSFER_NEG) {
2005		struct ccb_trans_settings *settings;
2006
2007		settings = (struct ccb_trans_settings *)async_arg;
2008		ata_set_transfer_settings(settings, device,
2009					  /*async_update*/TRUE);
2010	}
2011}
2012
2013static void
2014ata_announce_periph(struct cam_periph *periph)
2015{
2016	struct	ccb_pathinq cpi;
2017	struct	ccb_trans_settings cts;
2018	struct	cam_path *path = periph->path;
2019	u_int	speed;
2020	u_int	mb;
2021
2022	mtx_assert(periph->sim->mtx, MA_OWNED);
2023
2024	xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
2025	cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
2026	cts.type = CTS_TYPE_CURRENT_SETTINGS;
2027	xpt_action((union ccb*)&cts);
2028	if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
2029		return;
2030	/* Ask the SIM for its base transfer speed */
2031	xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
2032	cpi.ccb_h.func_code = XPT_PATH_INQ;
2033	xpt_action((union ccb *)&cpi);
2034	/* Report connection speed */
2035	speed = cpi.base_transfer_speed;
2036	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
2037		struct	ccb_trans_settings_pata *pata =
2038		    &cts.xport_specific.ata;
2039
2040		if (pata->valid & CTS_ATA_VALID_MODE)
2041			speed = ata_mode2speed(pata->mode);
2042	}
2043	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
2044		struct	ccb_trans_settings_sata *sata =
2045		    &cts.xport_specific.sata;
2046
2047		if (sata->valid & CTS_SATA_VALID_REVISION)
2048			speed = ata_revision2speed(sata->revision);
2049	}
2050	mb = speed / 1000;
2051	if (mb > 0)
2052		printf("%s%d: %d.%03dMB/s transfers",
2053		       periph->periph_name, periph->unit_number,
2054		       mb, speed % 1000);
2055	else
2056		printf("%s%d: %dKB/s transfers", periph->periph_name,
2057		       periph->unit_number, speed);
2058	/* Report additional information about connection */
2059	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
2060		struct ccb_trans_settings_pata *pata =
2061		    &cts.xport_specific.ata;
2062
2063		printf(" (");
2064		if (pata->valid & CTS_ATA_VALID_MODE)
2065			printf("%s, ", ata_mode2string(pata->mode));
2066		if ((pata->valid & CTS_ATA_VALID_ATAPI) && pata->atapi != 0)
2067			printf("ATAPI %dbytes, ", pata->atapi);
2068		if (pata->valid & CTS_ATA_VALID_BYTECOUNT)
2069			printf("PIO %dbytes", pata->bytecount);
2070		printf(")");
2071	}
2072	if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
2073		struct ccb_trans_settings_sata *sata =
2074		    &cts.xport_specific.sata;
2075
2076		printf(" (");
2077		if (sata->valid & CTS_SATA_VALID_REVISION)
2078			printf("SATA %d.x, ", sata->revision);
2079		else
2080			printf("SATA, ");
2081		if (sata->valid & CTS_SATA_VALID_MODE)
2082			printf("%s, ", ata_mode2string(sata->mode));
2083		if ((sata->valid & CTS_ATA_VALID_ATAPI) && sata->atapi != 0)
2084			printf("ATAPI %dbytes, ", sata->atapi);
2085		if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
2086			printf("PIO %dbytes", sata->bytecount);
2087		printf(")");
2088	}
2089	printf("\n");
2090}
2091
2092