xref: /freebsd/sys/cam/ata/ata_da.c (revision 0f2bd1e89db1a2f09268edea21e0ead329e092df)
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$");
29 
30 #include <sys/param.h>
31 
32 #ifdef _KERNEL
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/bio.h>
36 #include <sys/sysctl.h>
37 #include <sys/taskqueue.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/conf.h>
41 #include <sys/devicestat.h>
42 #include <sys/eventhandler.h>
43 #include <sys/malloc.h>
44 #include <sys/cons.h>
45 #include <geom/geom_disk.h>
46 #endif /* _KERNEL */
47 
48 #ifndef _KERNEL
49 #include <stdio.h>
50 #include <string.h>
51 #endif /* _KERNEL */
52 
53 #include <cam/cam.h>
54 #include <cam/cam_ccb.h>
55 #include <cam/cam_periph.h>
56 #include <cam/cam_xpt_periph.h>
57 #include <cam/cam_sim.h>
58 
59 #include <cam/ata/ata_all.h>
60 
61 #include <machine/md_var.h>	/* geometry translation */
62 
63 #ifdef _KERNEL
64 
65 #define ATA_MAX_28BIT_LBA               268435455UL
66 
67 typedef enum {
68 	ADA_STATE_NORMAL
69 } ada_state;
70 
71 typedef enum {
72 	ADA_FLAG_PACK_INVALID	= 0x001,
73 	ADA_FLAG_CAN_48BIT	= 0x002,
74 	ADA_FLAG_CAN_FLUSHCACHE	= 0x004,
75 	ADA_FLAG_CAN_NCQ	= 0x008,
76 	ADA_FLAG_CAN_DMA	= 0x010,
77 	ADA_FLAG_NEED_OTAG	= 0x020,
78 	ADA_FLAG_WENT_IDLE	= 0x040,
79 	ADA_FLAG_CAN_TRIM	= 0x080,
80 	ADA_FLAG_OPEN		= 0x100,
81 	ADA_FLAG_SCTX_INIT	= 0x200,
82 	ADA_FLAG_CAN_CFA        = 0x400
83 } ada_flags;
84 
85 typedef enum {
86 	ADA_Q_NONE		= 0x00
87 } ada_quirks;
88 
89 typedef enum {
90 	ADA_CCB_BUFFER_IO	= 0x03,
91 	ADA_CCB_WAITING		= 0x04,
92 	ADA_CCB_DUMP		= 0x05,
93 	ADA_CCB_TRIM		= 0x06,
94 	ADA_CCB_TYPE_MASK	= 0x0F,
95 } ada_ccb_state;
96 
97 /* Offsets into our private area for storing information */
98 #define ccb_state	ppriv_field0
99 #define ccb_bp		ppriv_ptr1
100 
101 struct disk_params {
102 	u_int8_t  heads;
103 	u_int8_t  secs_per_track;
104 	u_int32_t cylinders;
105 	u_int32_t secsize;	/* Number of bytes/logical sector */
106 	u_int64_t sectors;	/* Total number sectors */
107 };
108 
109 #define TRIM_MAX_BLOCKS	4
110 #define TRIM_MAX_RANGES	TRIM_MAX_BLOCKS * 64
111 struct trim_request {
112 	uint8_t		data[TRIM_MAX_RANGES * 8];
113 	struct bio	*bps[TRIM_MAX_RANGES];
114 };
115 
116 struct ada_softc {
117 	struct	 bio_queue_head bio_queue;
118 	struct	 bio_queue_head trim_queue;
119 	ada_state state;
120 	ada_flags flags;
121 	ada_quirks quirks;
122 	int	 ordered_tag_count;
123 	int	 outstanding_cmds;
124 	int	 trim_max_ranges;
125 	int	 trim_running;
126 	struct	 disk_params params;
127 	struct	 disk *disk;
128 	struct task		sysctl_task;
129 	struct sysctl_ctx_list	sysctl_ctx;
130 	struct sysctl_oid	*sysctl_tree;
131 	struct callout		sendordered_c;
132 	struct trim_request	trim_req;
133 };
134 
135 struct ada_quirk_entry {
136 	struct scsi_inquiry_pattern inq_pat;
137 	ada_quirks quirks;
138 };
139 
140 static struct ada_quirk_entry ada_quirk_table[] =
141 {
142 	{
143 		/* Default */
144 		{
145 		  T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
146 		  /*vendor*/"*", /*product*/"*", /*revision*/"*"
147 		},
148 		/*quirks*/0
149 	},
150 };
151 
152 static	disk_strategy_t	adastrategy;
153 static	dumper_t	adadump;
154 static	periph_init_t	adainit;
155 static	void		adaasync(void *callback_arg, u_int32_t code,
156 				struct cam_path *path, void *arg);
157 static	void		adasysctlinit(void *context, int pending);
158 static	periph_ctor_t	adaregister;
159 static	periph_dtor_t	adacleanup;
160 static	periph_start_t	adastart;
161 static	periph_oninv_t	adaoninvalidate;
162 static	void		adadone(struct cam_periph *periph,
163 			       union ccb *done_ccb);
164 static  int		adaerror(union ccb *ccb, u_int32_t cam_flags,
165 				u_int32_t sense_flags);
166 static void		adagetparams(struct cam_periph *periph,
167 				struct ccb_getdev *cgd);
168 static timeout_t	adasendorderedtag;
169 static void		adashutdown(void *arg, int howto);
170 
171 #ifndef ADA_DEFAULT_TIMEOUT
172 #define ADA_DEFAULT_TIMEOUT 30	/* Timeout in seconds */
173 #endif
174 
175 #ifndef	ADA_DEFAULT_RETRY
176 #define	ADA_DEFAULT_RETRY	4
177 #endif
178 
179 #ifndef	ADA_DEFAULT_SEND_ORDERED
180 #define	ADA_DEFAULT_SEND_ORDERED	1
181 #endif
182 
183 /*
184  * Most platforms map firmware geometry to actual, but some don't.  If
185  * not overridden, default to nothing.
186  */
187 #ifndef ata_disk_firmware_geom_adjust
188 #define	ata_disk_firmware_geom_adjust(disk)
189 #endif
190 
191 static int ada_retry_count = ADA_DEFAULT_RETRY;
192 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT;
193 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED;
194 
195 SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0,
196             "CAM Direct Access Disk driver");
197 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RW,
198            &ada_retry_count, 0, "Normal I/O retry count");
199 TUNABLE_INT("kern.cam.ada.retry_count", &ada_retry_count);
200 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW,
201            &ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
202 TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout);
203 SYSCTL_INT(_kern_cam_ada, OID_AUTO, ada_send_ordered, CTLFLAG_RW,
204            &ada_send_ordered, 0, "Send Ordered Tags");
205 TUNABLE_INT("kern.cam.ada.ada_send_ordered", &ada_send_ordered);
206 
207 /*
208  * ADA_ORDEREDTAG_INTERVAL determines how often, relative
209  * to the default timeout, we check to see whether an ordered
210  * tagged transaction is appropriate to prevent simple tag
211  * starvation.  Since we'd like to ensure that there is at least
212  * 1/2 of the timeout length left for a starved transaction to
213  * complete after we've sent an ordered tag, we must poll at least
214  * four times in every timeout period.  This takes care of the worst
215  * case where a starved transaction starts during an interval that
216  * meets the requirement "don't send an ordered tag" test so it takes
217  * us two intervals to determine that a tag must be sent.
218  */
219 #ifndef ADA_ORDEREDTAG_INTERVAL
220 #define ADA_ORDEREDTAG_INTERVAL 4
221 #endif
222 
223 static struct periph_driver adadriver =
224 {
225 	adainit, "ada",
226 	TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0
227 };
228 
229 PERIPHDRIVER_DECLARE(ada, adadriver);
230 
231 MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers");
232 
233 static int
234 adaopen(struct disk *dp)
235 {
236 	struct cam_periph *periph;
237 	struct ada_softc *softc;
238 	int unit;
239 	int error;
240 
241 	periph = (struct cam_periph *)dp->d_drv1;
242 	if (periph == NULL) {
243 		return (ENXIO);
244 	}
245 
246 	if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
247 		return(ENXIO);
248 	}
249 
250 	cam_periph_lock(periph);
251 	if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
252 		cam_periph_unlock(periph);
253 		cam_periph_release(periph);
254 		return (error);
255 	}
256 
257 	unit = periph->unit_number;
258 	softc = (struct ada_softc *)periph->softc;
259 	softc->flags |= ADA_FLAG_OPEN;
260 
261 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
262 	    ("adaopen: disk=%s%d (unit %d)\n", dp->d_name, dp->d_unit,
263 	     unit));
264 
265 	if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) {
266 		/* Invalidate our pack information. */
267 		softc->flags &= ~ADA_FLAG_PACK_INVALID;
268 	}
269 
270 	cam_periph_unhold(periph);
271 	cam_periph_unlock(periph);
272 	return (0);
273 }
274 
275 static int
276 adaclose(struct disk *dp)
277 {
278 	struct	cam_periph *periph;
279 	struct	ada_softc *softc;
280 	union ccb *ccb;
281 	int error;
282 
283 	periph = (struct cam_periph *)dp->d_drv1;
284 	if (periph == NULL)
285 		return (ENXIO);
286 
287 	cam_periph_lock(periph);
288 	if ((error = cam_periph_hold(periph, PRIBIO)) != 0) {
289 		cam_periph_unlock(periph);
290 		cam_periph_release(periph);
291 		return (error);
292 	}
293 
294 	softc = (struct ada_softc *)periph->softc;
295 	/* We only sync the cache if the drive is capable of it. */
296 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
297 
298 		ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
299 		cam_fill_ataio(&ccb->ataio,
300 				    1,
301 				    adadone,
302 				    CAM_DIR_NONE,
303 				    0,
304 				    NULL,
305 				    0,
306 				    ada_default_timeout*1000);
307 
308 		if (softc->flags & ADA_FLAG_CAN_48BIT)
309 			ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
310 		else
311 			ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
312 		cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
313 		    /*sense_flags*/0, softc->disk->d_devstat);
314 
315 		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
316 			xpt_print(periph->path, "Synchronize cache failed\n");
317 
318 		if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
319 			cam_release_devq(ccb->ccb_h.path,
320 					 /*relsim_flags*/0,
321 					 /*reduction*/0,
322 					 /*timeout*/0,
323 					 /*getcount_only*/0);
324 		xpt_release_ccb(ccb);
325 	}
326 
327 	softc->flags &= ~ADA_FLAG_OPEN;
328 	cam_periph_unhold(periph);
329 	cam_periph_unlock(periph);
330 	cam_periph_release(periph);
331 	return (0);
332 }
333 
334 static void
335 adaschedule(struct cam_periph *periph)
336 {
337 	struct ada_softc *softc = (struct ada_softc *)periph->softc;
338 
339 	if (bioq_first(&softc->bio_queue) ||
340 	    (!softc->trim_running && bioq_first(&softc->trim_queue))) {
341 		/* Have more work to do, so ensure we stay scheduled */
342 		xpt_schedule(periph, CAM_PRIORITY_NORMAL);
343 	}
344 }
345 
346 /*
347  * Actually translate the requested transfer into one the physical driver
348  * can understand.  The transfer is described by a buf and will include
349  * only one physical transfer.
350  */
351 static void
352 adastrategy(struct bio *bp)
353 {
354 	struct cam_periph *periph;
355 	struct ada_softc *softc;
356 
357 	periph = (struct cam_periph *)bp->bio_disk->d_drv1;
358 	if (periph == NULL) {
359 		biofinish(bp, NULL, ENXIO);
360 		return;
361 	}
362 	softc = (struct ada_softc *)periph->softc;
363 
364 	cam_periph_lock(periph);
365 
366 	/*
367 	 * If the device has been made invalid, error out
368 	 */
369 	if ((softc->flags & ADA_FLAG_PACK_INVALID)) {
370 		cam_periph_unlock(periph);
371 		biofinish(bp, NULL, ENXIO);
372 		return;
373 	}
374 
375 	/*
376 	 * Place it in the queue of disk activities for this disk
377 	 */
378 	if (bp->bio_cmd == BIO_DELETE &&
379 	    (softc->flags & ADA_FLAG_CAN_TRIM))
380 		bioq_disksort(&softc->trim_queue, bp);
381 	else
382 		bioq_disksort(&softc->bio_queue, bp);
383 
384 	/*
385 	 * Schedule ourselves for performing the work.
386 	 */
387 	adaschedule(periph);
388 	cam_periph_unlock(periph);
389 
390 	return;
391 }
392 
393 static int
394 adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
395 {
396 	struct	    cam_periph *periph;
397 	struct	    ada_softc *softc;
398 	u_int	    secsize;
399 	union	    ccb ccb;
400 	struct	    disk *dp;
401 	uint64_t    lba;
402 	uint16_t    count;
403 
404 	dp = arg;
405 	periph = dp->d_drv1;
406 	if (periph == NULL)
407 		return (ENXIO);
408 	softc = (struct ada_softc *)periph->softc;
409 	cam_periph_lock(periph);
410 	secsize = softc->params.secsize;
411 	lba = offset / secsize;
412 	count = length / secsize;
413 
414 	if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) {
415 		cam_periph_unlock(periph);
416 		return (ENXIO);
417 	}
418 
419 	if (length > 0) {
420 		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
421 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
422 		cam_fill_ataio(&ccb.ataio,
423 		    0,
424 		    adadone,
425 		    CAM_DIR_OUT,
426 		    0,
427 		    (u_int8_t *) virtual,
428 		    length,
429 		    ada_default_timeout*1000);
430 		if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
431 		    (lba + count >= ATA_MAX_28BIT_LBA ||
432 		    count >= 256)) {
433 			ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48,
434 			    0, lba, count);
435 		} else {
436 			ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA,
437 			    0, lba, count);
438 		}
439 		xpt_polled_action(&ccb);
440 
441 		if ((ccb.ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
442 			printf("Aborting dump due to I/O error.\n");
443 			cam_periph_unlock(periph);
444 			return(EIO);
445 		}
446 		cam_periph_unlock(periph);
447 		return(0);
448 	}
449 
450 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
451 		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
452 
453 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
454 		cam_fill_ataio(&ccb.ataio,
455 				    1,
456 				    adadone,
457 				    CAM_DIR_NONE,
458 				    0,
459 				    NULL,
460 				    0,
461 				    ada_default_timeout*1000);
462 
463 		if (softc->flags & ADA_FLAG_CAN_48BIT)
464 			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
465 		else
466 			ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
467 		xpt_polled_action(&ccb);
468 
469 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
470 			xpt_print(periph->path, "Synchronize cache failed\n");
471 
472 		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
473 			cam_release_devq(ccb.ccb_h.path,
474 					 /*relsim_flags*/0,
475 					 /*reduction*/0,
476 					 /*timeout*/0,
477 					 /*getcount_only*/0);
478 	}
479 	cam_periph_unlock(periph);
480 	return (0);
481 }
482 
483 static void
484 adainit(void)
485 {
486 	cam_status status;
487 
488 	/*
489 	 * Install a global async callback.  This callback will
490 	 * receive async callbacks like "new device found".
491 	 */
492 	status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL);
493 
494 	if (status != CAM_REQ_CMP) {
495 		printf("ada: Failed to attach master async callback "
496 		       "due to status 0x%x!\n", status);
497 	} else if (ada_send_ordered) {
498 
499 		/* Register our shutdown event handler */
500 		if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown,
501 					   NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
502 		    printf("adainit: shutdown event registration failed!\n");
503 	}
504 }
505 
506 static void
507 adaoninvalidate(struct cam_periph *periph)
508 {
509 	struct ada_softc *softc;
510 
511 	softc = (struct ada_softc *)periph->softc;
512 
513 	/*
514 	 * De-register any async callbacks.
515 	 */
516 	xpt_register_async(0, adaasync, periph, periph->path);
517 
518 	softc->flags |= ADA_FLAG_PACK_INVALID;
519 
520 	/*
521 	 * Return all queued I/O with ENXIO.
522 	 * XXX Handle any transactions queued to the card
523 	 *     with XPT_ABORT_CCB.
524 	 */
525 	bioq_flush(&softc->bio_queue, NULL, ENXIO);
526 	bioq_flush(&softc->trim_queue, NULL, ENXIO);
527 
528 	disk_gone(softc->disk);
529 	xpt_print(periph->path, "lost device\n");
530 }
531 
532 static void
533 adacleanup(struct cam_periph *periph)
534 {
535 	struct ada_softc *softc;
536 
537 	softc = (struct ada_softc *)periph->softc;
538 
539 	xpt_print(periph->path, "removing device entry\n");
540 	cam_periph_unlock(periph);
541 
542 	/*
543 	 * If we can't free the sysctl tree, oh well...
544 	 */
545 	if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0
546 	    && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
547 		xpt_print(periph->path, "can't remove sysctl context\n");
548 	}
549 
550 	disk_destroy(softc->disk);
551 	callout_drain(&softc->sendordered_c);
552 	free(softc, M_DEVBUF);
553 	cam_periph_lock(periph);
554 }
555 
556 static void
557 adaasync(void *callback_arg, u_int32_t code,
558 	struct cam_path *path, void *arg)
559 {
560 	struct cam_periph *periph;
561 
562 	periph = (struct cam_periph *)callback_arg;
563 	switch (code) {
564 	case AC_FOUND_DEVICE:
565 	{
566 		struct ccb_getdev *cgd;
567 		cam_status status;
568 
569 		cgd = (struct ccb_getdev *)arg;
570 		if (cgd == NULL)
571 			break;
572 
573 		if (cgd->protocol != PROTO_ATA)
574 			break;
575 
576 		/*
577 		 * Allocate a peripheral instance for
578 		 * this device and start the probe
579 		 * process.
580 		 */
581 		status = cam_periph_alloc(adaregister, adaoninvalidate,
582 					  adacleanup, adastart,
583 					  "ada", CAM_PERIPH_BIO,
584 					  cgd->ccb_h.path, adaasync,
585 					  AC_FOUND_DEVICE, cgd);
586 
587 		if (status != CAM_REQ_CMP
588 		 && status != CAM_REQ_INPROG)
589 			printf("adaasync: Unable to attach to new device "
590 				"due to status 0x%x\n", status);
591 		break;
592 	}
593 	default:
594 		cam_periph_async(periph, code, path, arg);
595 		break;
596 	}
597 }
598 
599 static void
600 adasysctlinit(void *context, int pending)
601 {
602 	struct cam_periph *periph;
603 	struct ada_softc *softc;
604 	char tmpstr[80], tmpstr2[80];
605 
606 	periph = (struct cam_periph *)context;
607 	if (cam_periph_acquire(periph) != CAM_REQ_CMP)
608 		return;
609 
610 	softc = (struct ada_softc *)periph->softc;
611 	snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d", periph->unit_number);
612 	snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
613 
614 	sysctl_ctx_init(&softc->sysctl_ctx);
615 	softc->flags |= ADA_FLAG_SCTX_INIT;
616 	softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
617 		SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2,
618 		CTLFLAG_RD, 0, tmpstr);
619 	if (softc->sysctl_tree == NULL) {
620 		printf("adasysctlinit: unable to allocate sysctl tree\n");
621 		cam_periph_release(periph);
622 		return;
623 	}
624 
625 	cam_periph_release(periph);
626 }
627 
628 static cam_status
629 adaregister(struct cam_periph *periph, void *arg)
630 {
631 	struct ada_softc *softc;
632 	struct ccb_pathinq cpi;
633 	struct ccb_getdev *cgd;
634 	char   announce_buf[80];
635 	struct disk_params *dp;
636 	caddr_t match;
637 	u_int maxio;
638 
639 	cgd = (struct ccb_getdev *)arg;
640 	if (periph == NULL) {
641 		printf("adaregister: periph was NULL!!\n");
642 		return(CAM_REQ_CMP_ERR);
643 	}
644 
645 	if (cgd == NULL) {
646 		printf("adaregister: no getdev CCB, can't register device\n");
647 		return(CAM_REQ_CMP_ERR);
648 	}
649 
650 	softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF,
651 	    M_NOWAIT|M_ZERO);
652 
653 	if (softc == NULL) {
654 		printf("adaregister: Unable to probe new device. "
655 		    "Unable to allocate softc\n");
656 		return(CAM_REQ_CMP_ERR);
657 	}
658 
659 	bioq_init(&softc->bio_queue);
660 	bioq_init(&softc->trim_queue);
661 
662 	if (cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA)
663 		softc->flags |= ADA_FLAG_CAN_DMA;
664 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
665 		softc->flags |= ADA_FLAG_CAN_48BIT;
666 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
667 		softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
668 	if (cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ &&
669 	    cgd->inq_flags & SID_CmdQue)
670 		softc->flags |= ADA_FLAG_CAN_NCQ;
671 	if (cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) {
672 		softc->flags |= ADA_FLAG_CAN_TRIM;
673 		softc->trim_max_ranges = TRIM_MAX_RANGES;
674 		if (cgd->ident_data.max_dsm_blocks != 0) {
675 			softc->trim_max_ranges =
676 			    min(cgd->ident_data.max_dsm_blocks * 64,
677 				softc->trim_max_ranges);
678 		}
679 	}
680 	if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
681 		softc->flags |= ADA_FLAG_CAN_CFA;
682 	softc->state = ADA_STATE_NORMAL;
683 
684 	periph->softc = softc;
685 
686 	/*
687 	 * See if this device has any quirks.
688 	 */
689 	match = cam_quirkmatch((caddr_t)&cgd->ident_data,
690 			       (caddr_t)ada_quirk_table,
691 			       sizeof(ada_quirk_table)/sizeof(*ada_quirk_table),
692 			       sizeof(*ada_quirk_table), ata_identify_match);
693 	if (match != NULL)
694 		softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
695 	else
696 		softc->quirks = ADA_Q_NONE;
697 
698 	bzero(&cpi, sizeof(cpi));
699 	xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE);
700 	cpi.ccb_h.func_code = XPT_PATH_INQ;
701 	xpt_action((union ccb *)&cpi);
702 
703 	TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
704 
705 	/*
706 	 * Register this media as a disk
707 	 */
708 	mtx_unlock(periph->sim->mtx);
709 	adagetparams(periph, cgd);
710 	softc->disk = disk_alloc();
711 	softc->disk->d_open = adaopen;
712 	softc->disk->d_close = adaclose;
713 	softc->disk->d_strategy = adastrategy;
714 	softc->disk->d_dump = adadump;
715 	softc->disk->d_name = "ada";
716 	softc->disk->d_drv1 = periph;
717 	maxio = cpi.maxio;		/* Honor max I/O size of SIM */
718 	if (maxio == 0)
719 		maxio = DFLTPHYS;	/* traditional default */
720 	else if (maxio > MAXPHYS)
721 		maxio = MAXPHYS;	/* for safety */
722 	if (softc->flags & ADA_FLAG_CAN_48BIT)
723 		maxio = min(maxio, 65536 * softc->params.secsize);
724 	else					/* 28bit ATA command limit */
725 		maxio = min(maxio, 256 * softc->params.secsize);
726 	softc->disk->d_maxsize = maxio;
727 	softc->disk->d_unit = periph->unit_number;
728 	softc->disk->d_flags = 0;
729 	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
730 		softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
731 	if ((softc->flags & ADA_FLAG_CAN_TRIM) ||
732 	    ((softc->flags & ADA_FLAG_CAN_CFA) &&
733 	    !(softc->flags & ADA_FLAG_CAN_48BIT)))
734 		softc->disk->d_flags |= DISKFLAG_CANDELETE;
735 	strlcpy(softc->disk->d_ident, cgd->serial_num,
736 	    MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1));
737 	softc->disk->d_hba_vendor = cpi.hba_vendor;
738 	softc->disk->d_hba_device = cpi.hba_device;
739 	softc->disk->d_hba_subvendor = cpi.hba_subvendor;
740 	softc->disk->d_hba_subdevice = cpi.hba_subdevice;
741 
742 	softc->disk->d_sectorsize = softc->params.secsize;
743 	softc->disk->d_mediasize = (off_t)softc->params.sectors *
744 	    softc->params.secsize;
745 	if (ata_physical_sector_size(&cgd->ident_data) !=
746 	    softc->params.secsize) {
747 		softc->disk->d_stripesize =
748 		    ata_physical_sector_size(&cgd->ident_data);
749 		softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
750 		    ata_logical_sector_offset(&cgd->ident_data)) %
751 		    softc->disk->d_stripesize;
752 	}
753 	softc->disk->d_fwsectors = softc->params.secs_per_track;
754 	softc->disk->d_fwheads = softc->params.heads;
755 	ata_disk_firmware_geom_adjust(softc->disk);
756 
757 	disk_create(softc->disk, DISK_VERSION);
758 	mtx_lock(periph->sim->mtx);
759 
760 	dp = &softc->params;
761 	snprintf(announce_buf, sizeof(announce_buf),
762 		"%juMB (%ju %u byte sectors: %dH %dS/T %dC)",
763 		(uintmax_t)(((uintmax_t)dp->secsize *
764 		dp->sectors) / (1024*1024)),
765 		(uintmax_t)dp->sectors,
766 		dp->secsize, dp->heads,
767 		dp->secs_per_track, dp->cylinders);
768 	xpt_announce_periph(periph, announce_buf);
769 	/*
770 	 * Add async callbacks for bus reset and
771 	 * bus device reset calls.  I don't bother
772 	 * checking if this fails as, in most cases,
773 	 * the system will function just fine without
774 	 * them and the only alternative would be to
775 	 * not attach the device on failure.
776 	 */
777 	xpt_register_async(AC_LOST_DEVICE,
778 			   adaasync, periph, periph->path);
779 
780 	/*
781 	 * Schedule a periodic event to occasionally send an
782 	 * ordered tag to a device.
783 	 */
784 	callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
785 	callout_reset(&softc->sendordered_c,
786 	    (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL,
787 	    adasendorderedtag, softc);
788 
789 	return(CAM_REQ_CMP);
790 }
791 
792 static void
793 adastart(struct cam_periph *periph, union ccb *start_ccb)
794 {
795 	struct ada_softc *softc = (struct ada_softc *)periph->softc;
796 	struct ccb_ataio *ataio = &start_ccb->ataio;
797 
798 	switch (softc->state) {
799 	case ADA_STATE_NORMAL:
800 	{
801 		struct bio *bp;
802 		u_int8_t tag_code;
803 
804 		/* Execute immediate CCB if waiting. */
805 		if (periph->immediate_priority <= periph->pinfo.priority) {
806 			CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
807 					("queuing for immediate ccb\n"));
808 			start_ccb->ccb_h.ccb_state = ADA_CCB_WAITING;
809 			SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
810 					  periph_links.sle);
811 			periph->immediate_priority = CAM_PRIORITY_NONE;
812 			wakeup(&periph->ccb_list);
813 			/* Have more work to do, so ensure we stay scheduled */
814 			adaschedule(periph);
815 			break;
816 		}
817 		/* Run TRIM if not running yet. */
818 		if (!softc->trim_running &&
819 		    (bp = bioq_first(&softc->trim_queue)) != 0) {
820 			struct trim_request *req = &softc->trim_req;
821 			struct bio *bp1;
822 			int bps = 0, ranges = 0;
823 
824 			softc->trim_running = 1;
825 			bzero(req, sizeof(*req));
826 			bp1 = bp;
827 			do {
828 				uint64_t lba = bp1->bio_pblkno;
829 				int count = bp1->bio_bcount /
830 				    softc->params.secsize;
831 
832 				bioq_remove(&softc->trim_queue, bp1);
833 				while (count > 0) {
834 					int c = min(count, 0xffff);
835 					int off = ranges * 8;
836 
837 					req->data[off + 0] = lba & 0xff;
838 					req->data[off + 1] = (lba >> 8) & 0xff;
839 					req->data[off + 2] = (lba >> 16) & 0xff;
840 					req->data[off + 3] = (lba >> 24) & 0xff;
841 					req->data[off + 4] = (lba >> 32) & 0xff;
842 					req->data[off + 5] = (lba >> 40) & 0xff;
843 					req->data[off + 6] = c & 0xff;
844 					req->data[off + 7] = (c >> 8) & 0xff;
845 					lba += c;
846 					count -= c;
847 					ranges++;
848 				}
849 				req->bps[bps++] = bp1;
850 				bp1 = bioq_first(&softc->trim_queue);
851 				if (bp1 == NULL ||
852 				    bp1->bio_bcount / softc->params.secsize >
853 				    (softc->trim_max_ranges - ranges) * 0xffff)
854 					break;
855 			} while (1);
856 			cam_fill_ataio(ataio,
857 			    ada_retry_count,
858 			    adadone,
859 			    CAM_DIR_OUT,
860 			    0,
861 			    req->data,
862 			    ((ranges + 63) / 64) * 512,
863 			    ada_default_timeout * 1000);
864 			ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
865 			    ATA_DSM_TRIM, 0, (ranges + 63) / 64);
866 			start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
867 			goto out;
868 		}
869 		/* Run regular command. */
870 		bp = bioq_first(&softc->bio_queue);
871 		if (bp == NULL) {
872 			xpt_release_ccb(start_ccb);
873 			break;
874 		}
875 		bioq_remove(&softc->bio_queue, bp);
876 
877 		if ((softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
878 			softc->flags &= ~ADA_FLAG_NEED_OTAG;
879 			softc->ordered_tag_count++;
880 			tag_code = 0;
881 		} else {
882 			tag_code = 1;
883 		}
884 		switch (bp->bio_cmd) {
885 		case BIO_READ:
886 		case BIO_WRITE:
887 		{
888 			uint64_t lba = bp->bio_pblkno;
889 			uint16_t count = bp->bio_bcount / softc->params.secsize;
890 
891 			cam_fill_ataio(ataio,
892 			    ada_retry_count,
893 			    adadone,
894 			    bp->bio_cmd == BIO_READ ?
895 			        CAM_DIR_IN : CAM_DIR_OUT,
896 			    tag_code,
897 			    bp->bio_data,
898 			    bp->bio_bcount,
899 			    ada_default_timeout*1000);
900 
901 			if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
902 				if (bp->bio_cmd == BIO_READ) {
903 					ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
904 					    lba, count);
905 				} else {
906 					ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
907 					    lba, count);
908 				}
909 			} else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
910 			    (lba + count >= ATA_MAX_28BIT_LBA ||
911 			    count > 256)) {
912 				if (softc->flags & ADA_FLAG_CAN_DMA) {
913 					if (bp->bio_cmd == BIO_READ) {
914 						ata_48bit_cmd(ataio, ATA_READ_DMA48,
915 						    0, lba, count);
916 					} else {
917 						ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
918 						    0, lba, count);
919 					}
920 				} else {
921 					if (bp->bio_cmd == BIO_READ) {
922 						ata_48bit_cmd(ataio, ATA_READ_MUL48,
923 						    0, lba, count);
924 					} else {
925 						ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
926 						    0, lba, count);
927 					}
928 				}
929 			} else {
930 				if (count == 256)
931 					count = 0;
932 				if (softc->flags & ADA_FLAG_CAN_DMA) {
933 					if (bp->bio_cmd == BIO_READ) {
934 						ata_28bit_cmd(ataio, ATA_READ_DMA,
935 						    0, lba, count);
936 					} else {
937 						ata_28bit_cmd(ataio, ATA_WRITE_DMA,
938 						    0, lba, count);
939 					}
940 				} else {
941 					if (bp->bio_cmd == BIO_READ) {
942 						ata_28bit_cmd(ataio, ATA_READ_MUL,
943 						    0, lba, count);
944 					} else {
945 						ata_28bit_cmd(ataio, ATA_WRITE_MUL,
946 						    0, lba, count);
947 					}
948 				}
949 			}
950 			break;
951 		}
952 		case BIO_DELETE:
953 		{
954 			uint64_t lba = bp->bio_pblkno;
955 			uint16_t count = bp->bio_bcount / softc->params.secsize;
956 
957 			cam_fill_ataio(ataio,
958 			    ada_retry_count,
959 			    adadone,
960 			    CAM_DIR_NONE,
961 			    0,
962 			    NULL,
963 			    0,
964 			    ada_default_timeout*1000);
965 
966 			if (count >= 256)
967 				count = 0;
968 			ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
969 			break;
970 		}
971 		case BIO_FLUSH:
972 			cam_fill_ataio(ataio,
973 			    1,
974 			    adadone,
975 			    CAM_DIR_NONE,
976 			    0,
977 			    NULL,
978 			    0,
979 			    ada_default_timeout*1000);
980 
981 			if (softc->flags & ADA_FLAG_CAN_48BIT)
982 				ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
983 			else
984 				ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
985 			break;
986 		}
987 		start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
988 out:
989 		start_ccb->ccb_h.ccb_bp = bp;
990 		softc->outstanding_cmds++;
991 		xpt_action(start_ccb);
992 
993 		/* May have more work to do, so ensure we stay scheduled */
994 		adaschedule(periph);
995 		break;
996 	}
997 	}
998 }
999 
1000 static void
1001 adadone(struct cam_periph *periph, union ccb *done_ccb)
1002 {
1003 	struct ada_softc *softc;
1004 	struct ccb_ataio *ataio;
1005 
1006 	softc = (struct ada_softc *)periph->softc;
1007 	ataio = &done_ccb->ataio;
1008 	switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
1009 	case ADA_CCB_BUFFER_IO:
1010 	case ADA_CCB_TRIM:
1011 	{
1012 		struct bio *bp;
1013 
1014 		bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1015 		if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1016 			int error;
1017 
1018 			error = adaerror(done_ccb, 0, 0);
1019 			if (error == ERESTART) {
1020 				/* A retry was scheduled, so just return. */
1021 				return;
1022 			}
1023 			if (error != 0) {
1024 				if (error == ENXIO) {
1025 					/*
1026 					 * Catastrophic error.  Mark our pack as
1027 					 * invalid.
1028 					 */
1029 					/*
1030 					 * XXX See if this is really a media
1031 					 * XXX change first?
1032 					 */
1033 					xpt_print(periph->path,
1034 					    "Invalidating pack\n");
1035 					softc->flags |= ADA_FLAG_PACK_INVALID;
1036 				}
1037 				bp->bio_error = error;
1038 				bp->bio_resid = bp->bio_bcount;
1039 				bp->bio_flags |= BIO_ERROR;
1040 			} else {
1041 				bp->bio_resid = ataio->resid;
1042 				bp->bio_error = 0;
1043 				if (bp->bio_resid != 0)
1044 					bp->bio_flags |= BIO_ERROR;
1045 			}
1046 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1047 				cam_release_devq(done_ccb->ccb_h.path,
1048 						 /*relsim_flags*/0,
1049 						 /*reduction*/0,
1050 						 /*timeout*/0,
1051 						 /*getcount_only*/0);
1052 		} else {
1053 			if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1054 				panic("REQ_CMP with QFRZN");
1055 			bp->bio_resid = ataio->resid;
1056 			if (ataio->resid > 0)
1057 				bp->bio_flags |= BIO_ERROR;
1058 		}
1059 		softc->outstanding_cmds--;
1060 		if (softc->outstanding_cmds == 0)
1061 			softc->flags |= ADA_FLAG_WENT_IDLE;
1062 		if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) ==
1063 		    ADA_CCB_TRIM) {
1064 			struct trim_request *req =
1065 			    (struct trim_request *)ataio->data_ptr;
1066 			int i;
1067 
1068 			for (i = 1; i < softc->trim_max_ranges &&
1069 			    req->bps[i]; i++) {
1070 				struct bio *bp1 = req->bps[i];
1071 
1072 				bp1->bio_resid = bp->bio_resid;
1073 				bp1->bio_error = bp->bio_error;
1074 				if (bp->bio_flags & BIO_ERROR)
1075 					bp1->bio_flags |= BIO_ERROR;
1076 				biodone(bp1);
1077 			}
1078 			softc->trim_running = 0;
1079 			biodone(bp);
1080 			adaschedule(periph);
1081 		} else
1082 			biodone(bp);
1083 		break;
1084 	}
1085 	case ADA_CCB_WAITING:
1086 	{
1087 		/* Caller will release the CCB */
1088 		wakeup(&done_ccb->ccb_h.cbfcnp);
1089 		return;
1090 	}
1091 	case ADA_CCB_DUMP:
1092 		/* No-op.  We're polling */
1093 		return;
1094 	default:
1095 		break;
1096 	}
1097 	xpt_release_ccb(done_ccb);
1098 }
1099 
1100 static int
1101 adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
1102 {
1103 	struct ada_softc	  *softc;
1104 	struct cam_periph *periph;
1105 
1106 	periph = xpt_path_periph(ccb->ccb_h.path);
1107 	softc = (struct ada_softc *)periph->softc;
1108 
1109 	return(cam_periph_error(ccb, cam_flags, sense_flags, NULL));
1110 }
1111 
1112 static void
1113 adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd)
1114 {
1115 	struct ada_softc *softc = (struct ada_softc *)periph->softc;
1116 	struct disk_params *dp = &softc->params;
1117 	u_int64_t lbasize48;
1118 	u_int32_t lbasize;
1119 
1120 	dp->secsize = ata_logical_sector_size(&cgd->ident_data);
1121 	if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
1122 		cgd->ident_data.current_heads && cgd->ident_data.current_sectors) {
1123 		dp->heads = cgd->ident_data.current_heads;
1124 		dp->secs_per_track = cgd->ident_data.current_sectors;
1125 		dp->cylinders = cgd->ident_data.cylinders;
1126 		dp->sectors = (u_int32_t)cgd->ident_data.current_size_1 |
1127 			  ((u_int32_t)cgd->ident_data.current_size_2 << 16);
1128 	} else {
1129 		dp->heads = cgd->ident_data.heads;
1130 		dp->secs_per_track = cgd->ident_data.sectors;
1131 		dp->cylinders = cgd->ident_data.cylinders;
1132 		dp->sectors = cgd->ident_data.cylinders * dp->heads * dp->secs_per_track;
1133 	}
1134 	lbasize = (u_int32_t)cgd->ident_data.lba_size_1 |
1135 		  ((u_int32_t)cgd->ident_data.lba_size_2 << 16);
1136 
1137 	/* use the 28bit LBA size if valid or bigger than the CHS mapping */
1138 	if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
1139 		dp->sectors = lbasize;
1140 
1141 	/* use the 48bit LBA size if valid */
1142 	lbasize48 = ((u_int64_t)cgd->ident_data.lba_size48_1) |
1143 		    ((u_int64_t)cgd->ident_data.lba_size48_2 << 16) |
1144 		    ((u_int64_t)cgd->ident_data.lba_size48_3 << 32) |
1145 		    ((u_int64_t)cgd->ident_data.lba_size48_4 << 48);
1146 	if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) &&
1147 	    lbasize48 > ATA_MAX_28BIT_LBA)
1148 		dp->sectors = lbasize48;
1149 }
1150 
1151 static void
1152 adasendorderedtag(void *arg)
1153 {
1154 	struct ada_softc *softc = arg;
1155 
1156 	if (ada_send_ordered) {
1157 		if ((softc->ordered_tag_count == 0)
1158 		 && ((softc->flags & ADA_FLAG_WENT_IDLE) == 0)) {
1159 			softc->flags |= ADA_FLAG_NEED_OTAG;
1160 		}
1161 		if (softc->outstanding_cmds > 0)
1162 			softc->flags &= ~ADA_FLAG_WENT_IDLE;
1163 
1164 		softc->ordered_tag_count = 0;
1165 	}
1166 	/* Queue us up again */
1167 	callout_reset(&softc->sendordered_c,
1168 	    (ADA_DEFAULT_TIMEOUT * hz) / ADA_ORDEREDTAG_INTERVAL,
1169 	    adasendorderedtag, softc);
1170 }
1171 
1172 /*
1173  * Step through all ADA peripheral drivers, and if the device is still open,
1174  * sync the disk cache to physical media.
1175  */
1176 static void
1177 adashutdown(void * arg, int howto)
1178 {
1179 	struct cam_periph *periph;
1180 	struct ada_softc *softc;
1181 
1182 	TAILQ_FOREACH(periph, &adadriver.units, unit_links) {
1183 		union ccb ccb;
1184 
1185 		/* If we paniced with lock held - not recurse here. */
1186 		if (cam_periph_owned(periph))
1187 			continue;
1188 		cam_periph_lock(periph);
1189 		softc = (struct ada_softc *)periph->softc;
1190 		/*
1191 		 * We only sync the cache if the drive is still open, and
1192 		 * if the drive is capable of it..
1193 		 */
1194 		if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
1195 		    (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
1196 			cam_periph_unlock(periph);
1197 			continue;
1198 		}
1199 
1200 		xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1201 
1202 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
1203 		cam_fill_ataio(&ccb.ataio,
1204 				    1,
1205 				    adadone,
1206 				    CAM_DIR_NONE,
1207 				    0,
1208 				    NULL,
1209 				    0,
1210 				    ada_default_timeout*1000);
1211 
1212 		if (softc->flags & ADA_FLAG_CAN_48BIT)
1213 			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1214 		else
1215 			ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
1216 		xpt_polled_action(&ccb);
1217 
1218 		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
1219 			xpt_print(periph->path, "Synchronize cache failed\n");
1220 
1221 		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
1222 			cam_release_devq(ccb.ccb_h.path,
1223 					 /*relsim_flags*/0,
1224 					 /*reduction*/0,
1225 					 /*timeout*/0,
1226 					 /*getcount_only*/0);
1227 		cam_periph_unlock(periph);
1228 	}
1229 }
1230 
1231 #endif /* _KERNEL */
1232