]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/cam/scsi/scsi_da.c
MFC r249981:
[FreeBSD/stable/9.git] / sys / cam / scsi / scsi_da.c
1 /*-
2  * Implementation of SCSI Direct Access Peripheral driver for CAM.
3  *
4  * Copyright (c) 1997 Justin T. Gibbs.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer,
12  *    without modification, immediately at the beginning of the file.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33
34 #ifdef _KERNEL
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/bio.h>
38 #include <sys/sysctl.h>
39 #include <sys/taskqueue.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/conf.h>
43 #include <sys/devicestat.h>
44 #include <sys/eventhandler.h>
45 #include <sys/malloc.h>
46 #include <sys/cons.h>
47 #include <sys/endian.h>
48 #include <sys/proc.h>
49 #include <geom/geom.h>
50 #include <geom/geom_disk.h>
51 #endif /* _KERNEL */
52
53 #ifndef _KERNEL
54 #include <stdio.h>
55 #include <string.h>
56 #endif /* _KERNEL */
57
58 #include <cam/cam.h>
59 #include <cam/cam_ccb.h>
60 #include <cam/cam_periph.h>
61 #include <cam/cam_xpt_periph.h>
62 #include <cam/cam_sim.h>
63
64 #include <cam/scsi/scsi_message.h>
65
66 #ifndef _KERNEL 
67 #include <cam/scsi/scsi_da.h>
68 #endif /* !_KERNEL */
69
70 #ifdef _KERNEL
71 typedef enum {
72         DA_STATE_PROBE_RC,
73         DA_STATE_PROBE_RC16,
74         DA_STATE_PROBE_LBP,
75         DA_STATE_PROBE_BLK_LIMITS,
76         DA_STATE_PROBE_BDC,
77         DA_STATE_PROBE_ATA,
78         DA_STATE_NORMAL
79 } da_state;
80
81 typedef enum {
82         DA_FLAG_PACK_INVALID    = 0x001,
83         DA_FLAG_NEW_PACK        = 0x002,
84         DA_FLAG_PACK_LOCKED     = 0x004,
85         DA_FLAG_PACK_REMOVABLE  = 0x008,
86         DA_FLAG_SAW_MEDIA       = 0x010,
87         DA_FLAG_NEED_OTAG       = 0x020,
88         DA_FLAG_WENT_IDLE       = 0x040,
89         DA_FLAG_RETRY_UA        = 0x080,
90         DA_FLAG_OPEN            = 0x100,
91         DA_FLAG_SCTX_INIT       = 0x200,
92         DA_FLAG_CAN_RC16        = 0x400,
93         DA_FLAG_PROBED          = 0x800,
94         DA_FLAG_DIRTY           = 0x1000
95 } da_flags;
96
97 typedef enum {
98         DA_Q_NONE               = 0x00,
99         DA_Q_NO_SYNC_CACHE      = 0x01,
100         DA_Q_NO_6_BYTE          = 0x02,
101         DA_Q_NO_PREVENT         = 0x04,
102         DA_Q_4K                 = 0x08,
103         DA_Q_NO_RC16            = 0x10
104 } da_quirks;
105
106 #define DA_Q_BIT_STRING         \
107         "\020"                  \
108         "\001NO_SYNC_CACHE"     \
109         "\002NO_6_BYTE"         \
110         "\003NO_PREVENT"        \
111         "\0044K"                \
112         "\005NO_RC16"
113
114 typedef enum {
115         DA_CCB_PROBE_RC         = 0x01,
116         DA_CCB_PROBE_RC16       = 0x02,
117         DA_CCB_PROBE_LBP        = 0x03,
118         DA_CCB_PROBE_BLK_LIMITS = 0x04,
119         DA_CCB_PROBE_BDC        = 0x05,
120         DA_CCB_PROBE_ATA        = 0x06,
121         DA_CCB_BUFFER_IO        = 0x07,
122         DA_CCB_WAITING          = 0x08,
123         DA_CCB_DUMP             = 0x0A,
124         DA_CCB_DELETE           = 0x0B,
125         DA_CCB_TUR              = 0x0C,
126         DA_CCB_TYPE_MASK        = 0x0F,
127         DA_CCB_RETRY_UA         = 0x10
128 } da_ccb_state;
129
130 /*
131  * Order here is important for method choice
132  *
133  * We prefer ATA_TRIM as tests run against a Sandforce 2281 SSD attached to
134  * LSI 2008 (mps) controller (FW: v12, Drv: v14) resulted 20% quicker deletes
135  * using ATA_TRIM than the corresponding UNMAP results for a real world mysql
136  * import taking 5mins.
137  *
138  */
139 typedef enum {
140         DA_DELETE_NONE,
141         DA_DELETE_DISABLE,
142         DA_DELETE_ATA_TRIM,
143         DA_DELETE_UNMAP,
144         DA_DELETE_WS16,
145         DA_DELETE_WS10,
146         DA_DELETE_ZERO,
147         DA_DELETE_MIN = DA_DELETE_ATA_TRIM,
148         DA_DELETE_MAX = DA_DELETE_ZERO
149 } da_delete_methods;
150
151 typedef void da_delete_func_t (struct cam_periph *periph, union ccb *ccb,
152                               struct bio *bp);
153 static da_delete_func_t da_delete_trim;
154 static da_delete_func_t da_delete_unmap;
155 static da_delete_func_t da_delete_ws;
156
157 static const void * da_delete_functions[] = {
158         NULL,
159         NULL,
160         da_delete_trim,
161         da_delete_unmap,
162         da_delete_ws,
163         da_delete_ws,
164         da_delete_ws
165 };
166
167 static const char *da_delete_method_names[] =
168     { "NONE", "DISABLE", "ATA_TRIM", "UNMAP", "WS16", "WS10", "ZERO" };
169 static const char *da_delete_method_desc[] =
170     { "NONE", "DISABLED", "ATA TRIM", "UNMAP", "WRITE SAME(16) with UNMAP",
171       "WRITE SAME(10) with UNMAP", "ZERO" };
172
173 /* Offsets into our private area for storing information */
174 #define ccb_state       ppriv_field0
175 #define ccb_bp          ppriv_ptr1
176
177 struct disk_params {
178         u_int8_t  heads;
179         u_int32_t cylinders;
180         u_int8_t  secs_per_track;
181         u_int32_t secsize;      /* Number of bytes/sector */
182         u_int64_t sectors;      /* total number sectors */
183         u_int     stripesize;
184         u_int     stripeoffset;
185 };
186
187 #define UNMAP_RANGE_MAX         0xffffffff
188 #define UNMAP_HEAD_SIZE         8
189 #define UNMAP_RANGE_SIZE        16
190 #define UNMAP_MAX_RANGES        2048 /* Protocol Max is 4095 */
191 #define UNMAP_BUF_SIZE          ((UNMAP_MAX_RANGES * UNMAP_RANGE_SIZE) + \
192                                 UNMAP_HEAD_SIZE)
193
194 #define WS10_MAX_BLKS           0xffff
195 #define WS16_MAX_BLKS           0xffffffff
196 #define ATA_TRIM_MAX_RANGES     ((UNMAP_BUF_SIZE / \
197         (ATA_DSM_RANGE_SIZE * ATA_DSM_BLK_SIZE)) * ATA_DSM_BLK_SIZE)
198
199 struct da_softc {
200         struct   bio_queue_head bio_queue;
201         struct   bio_queue_head delete_queue;
202         struct   bio_queue_head delete_run_queue;
203         SLIST_ENTRY(da_softc) links;
204         LIST_HEAD(, ccb_hdr) pending_ccbs;
205         da_state state;
206         da_flags flags; 
207         da_quirks quirks;
208         int      sort_io_queue;
209         int      minimum_cmd_size;
210         int      error_inject;
211         int      ordered_tag_count;
212         int      outstanding_cmds;
213         int      trim_max_ranges;
214         int      delete_running;
215         int      tur;
216         int      delete_available;      /* Delete methods possibly available */
217         uint32_t                unmap_max_ranges;
218         uint32_t                unmap_max_lba;
219         uint64_t                ws_max_blks;
220         da_delete_methods       delete_method;
221         da_delete_func_t        *delete_func;
222         struct   disk_params params;
223         struct   disk *disk;
224         union    ccb saved_ccb;
225         struct task             sysctl_task;
226         struct sysctl_ctx_list  sysctl_ctx;
227         struct sysctl_oid       *sysctl_tree;
228         struct callout          sendordered_c;
229         uint64_t wwpn;
230         uint8_t  unmap_buf[UNMAP_BUF_SIZE];
231         struct scsi_read_capacity_data_long rcaplong;
232         struct callout          mediapoll_c;
233 };
234
235 #define dadeleteflag(softc, delete_method, enable)                      \
236         if (enable) {                                                   \
237                 softc->delete_available |= (1 << delete_method);        \
238         } else {                                                        \
239                 softc->delete_available &= ~(1 << delete_method);       \
240         }
241
242 struct da_quirk_entry {
243         struct scsi_inquiry_pattern inq_pat;
244         da_quirks quirks;
245 };
246
247 static const char quantum[] = "QUANTUM";
248 static const char microp[] = "MICROP";
249
250 static struct da_quirk_entry da_quirk_table[] =
251 {
252         /* SPI, FC devices */
253         {
254                 /*
255                  * Fujitsu M2513A MO drives.
256                  * Tested devices: M2513A2 firmware versions 1200 & 1300.
257                  * (dip switch selects whether T_DIRECT or T_OPTICAL device)
258                  * Reported by: W.Scholten <whs@xs4all.nl>
259                  */
260                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
261                 /*quirks*/ DA_Q_NO_SYNC_CACHE
262         },
263         {
264                 /* See above. */
265                 {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
266                 /*quirks*/ DA_Q_NO_SYNC_CACHE
267         },
268         {
269                 /*
270                  * This particular Fujitsu drive doesn't like the
271                  * synchronize cache command.
272                  * Reported by: Tom Jackson <toj@gorilla.net>
273                  */
274                 {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
275                 /*quirks*/ DA_Q_NO_SYNC_CACHE
276         },
277         {
278                 /*
279                  * This drive doesn't like the synchronize cache command
280                  * either.  Reported by: Matthew Jacob <mjacob@feral.com>
281                  * in NetBSD PR kern/6027, August 24, 1998.
282                  */
283                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
284                 /*quirks*/ DA_Q_NO_SYNC_CACHE
285         },
286         {
287                 /*
288                  * This drive doesn't like the synchronize cache command
289                  * either.  Reported by: Hellmuth Michaelis (hm@kts.org)
290                  * (PR 8882).
291                  */
292                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
293                 /*quirks*/ DA_Q_NO_SYNC_CACHE
294         },
295         {
296                 /*
297                  * Doesn't like the synchronize cache command.
298                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
299                  */
300                 {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
301                 /*quirks*/ DA_Q_NO_SYNC_CACHE
302         },
303         {
304                 /*
305                  * Doesn't like the synchronize cache command.
306                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
307                  */
308                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
309                 /*quirks*/ DA_Q_NO_SYNC_CACHE
310         },
311         {
312                 /*
313                  * Doesn't like the synchronize cache command.
314                  */
315                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
316                 /*quirks*/ DA_Q_NO_SYNC_CACHE
317         },
318         {
319                 /*
320                  * Doesn't like the synchronize cache command.
321                  * Reported by: walter@pelissero.de
322                  */
323                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
324                 /*quirks*/ DA_Q_NO_SYNC_CACHE
325         },
326         {
327                 /*
328                  * Doesn't work correctly with 6 byte reads/writes.
329                  * Returns illegal request, and points to byte 9 of the
330                  * 6-byte CDB.
331                  * Reported by:  Adam McDougall <bsdx@spawnet.com>
332                  */
333                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
334                 /*quirks*/ DA_Q_NO_6_BYTE
335         },
336         {
337                 /* See above. */
338                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
339                 /*quirks*/ DA_Q_NO_6_BYTE
340         },
341         {
342                 /*
343                  * Doesn't like the synchronize cache command.
344                  * Reported by: walter@pelissero.de
345                  */
346                 {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
347                 /*quirks*/ DA_Q_NO_SYNC_CACHE
348         },
349         {
350                 /*
351                  * The CISS RAID controllers do not support SYNC_CACHE
352                  */
353                 {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
354                 /*quirks*/ DA_Q_NO_SYNC_CACHE
355         },
356         /* USB mass storage devices supported by umass(4) */
357         {
358                 /*
359                  * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
360                  * PR: kern/51675
361                  */
362                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
363                 /*quirks*/ DA_Q_NO_SYNC_CACHE
364         },
365         {
366                 /*
367                  * Power Quotient Int. (PQI) USB flash key
368                  * PR: kern/53067
369                  */
370                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
371                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
372         },
373         {
374                 /*
375                  * Creative Nomad MUVO mp3 player (USB)
376                  * PR: kern/53094
377                  */
378                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
379                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
380         },
381         {
382                 /*
383                  * Jungsoft NEXDISK USB flash key
384                  * PR: kern/54737
385                  */
386                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
387                 /*quirks*/ DA_Q_NO_SYNC_CACHE
388         },
389         {
390                 /*
391                  * FreeDik USB Mini Data Drive
392                  * PR: kern/54786
393                  */
394                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive",
395                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
396         },
397         {
398                 /*
399                  * Sigmatel USB Flash MP3 Player
400                  * PR: kern/57046
401                  */
402                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
403                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
404         },
405         {
406                 /*
407                  * Neuros USB Digital Audio Computer
408                  * PR: kern/63645
409                  */
410                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
411                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
412         },
413         {
414                 /*
415                  * SEAGRAND NP-900 MP3 Player
416                  * PR: kern/64563
417                  */
418                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
419                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
420         },
421         {
422                 /*
423                  * iRiver iFP MP3 player (with UMS Firmware)
424                  * PR: kern/54881, i386/63941, kern/66124
425                  */
426                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"},
427                 /*quirks*/ DA_Q_NO_SYNC_CACHE
428         },
429         {
430                 /*
431                  * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
432                  * PR: kern/70158
433                  */
434                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
435                 /*quirks*/ DA_Q_NO_SYNC_CACHE
436         },
437         {
438                 /*
439                  * ZICPlay USB MP3 Player with FM
440                  * PR: kern/75057
441                  */
442                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
443                 /*quirks*/ DA_Q_NO_SYNC_CACHE
444         },
445         {
446                 /*
447                  * TEAC USB floppy mechanisms
448                  */
449                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
450                 /*quirks*/ DA_Q_NO_SYNC_CACHE
451         },
452         {
453                 /*
454                  * Kingston DataTraveler II+ USB Pen-Drive.
455                  * Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
456                  */
457                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+",
458                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
459         },
460         {
461                 /*
462                  * USB DISK Pro PMAP
463                  * Reported by: jhs
464                  * PR: usb/96381
465                  */
466                 {T_DIRECT, SIP_MEDIA_REMOVABLE, " ", "USB DISK Pro", "PMAP"},
467                 /*quirks*/ DA_Q_NO_SYNC_CACHE
468         },
469         {
470                 /*
471                  * Motorola E398 Mobile Phone (TransFlash memory card).
472                  * Reported by: Wojciech A. Koszek <dunstan@FreeBSD.czest.pl>
473                  * PR: usb/89889
474                  */
475                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone",
476                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
477         },
478         {
479                 /*
480                  * Qware BeatZkey! Pro
481                  * PR: usb/79164
482                  */
483                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE",
484                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
485         },
486         {
487                 /*
488                  * Time DPA20B 1GB MP3 Player
489                  * PR: usb/81846
490                  */
491                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*",
492                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
493         },
494         {
495                 /*
496                  * Samsung USB key 128Mb
497                  * PR: usb/90081
498                  */
499                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb",
500                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
501         },
502         {
503                 /*
504                  * Kingston DataTraveler 2.0 USB Flash memory.
505                  * PR: usb/89196
506                  */
507                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0",
508                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
509         },
510         {
511                 /*
512                  * Creative MUVO Slim mp3 player (USB)
513                  * PR: usb/86131
514                  */
515                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
516                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
517                 },
518         {
519                 /*
520                  * United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3)
521                  * PR: usb/80487
522                  */
523                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK",
524                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
525         },
526         {
527                 /*
528                  * SanDisk Micro Cruzer 128MB
529                  * PR: usb/75970
530                  */
531                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer",
532                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
533         },
534         {
535                 /*
536                  * TOSHIBA TransMemory USB sticks
537                  * PR: kern/94660
538                  */
539                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory",
540                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
541         },
542         {
543                 /*
544                  * PNY USB Flash keys
545                  * PR: usb/75578, usb/72344, usb/65436 
546                  */
547                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
548                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
549         },
550         {
551                 /*
552                  * Genesys 6-in-1 Card Reader
553                  * PR: usb/94647
554                  */
555                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
556                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
557         },
558         {
559                 /*
560                  * Rekam Digital CAMERA
561                  * PR: usb/98713
562                  */
563                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*",
564                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
565         },
566         {
567                 /*
568                  * iRiver H10 MP3 player
569                  * PR: usb/102547
570                  */
571                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*",
572                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
573         },
574         {
575                 /*
576                  * iRiver U10 MP3 player
577                  * PR: usb/92306
578                  */
579                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "U10*",
580                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
581         },
582         {
583                 /*
584                  * X-Micro Flash Disk
585                  * PR: usb/96901
586                  */
587                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro", "Flash Disk",
588                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
589         },
590         {
591                 /*
592                  * EasyMP3 EM732X USB 2.0 Flash MP3 Player
593                  * PR: usb/96546
594                  */
595                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*",
596                 "1.00"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
597         },
598         {
599                 /*
600                  * Denver MP3 player
601                  * PR: usb/107101
602                  */
603                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "DENVER", "MP3 PLAYER",
604                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
605         },
606         {
607                 /*
608                  * Philips USB Key Audio KEY013
609                  * PR: usb/68412
610                  */
611                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "PHILIPS", "Key*", "*"},
612                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
613         },
614         {
615                 /*
616                  * JNC MP3 Player
617                  * PR: usb/94439
618                  */
619                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JNC*" , "MP3 Player*",
620                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
621         },
622         {
623                 /*
624                  * SAMSUNG MP0402H
625                  * PR: usb/108427
626                  */
627                 {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "MP0402H", "*"},
628                 /*quirks*/ DA_Q_NO_SYNC_CACHE
629         },
630         {
631                 /*
632                  * I/O Magic USB flash - Giga Bank
633                  * PR: usb/108810
634                  */
635                 {T_DIRECT, SIP_MEDIA_FIXED, "GS-Magic", "stor*", "*"},
636                 /*quirks*/ DA_Q_NO_SYNC_CACHE
637         },
638         {
639                 /*
640                  * JoyFly 128mb USB Flash Drive
641                  * PR: 96133
642                  */
643                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "Flash Disk*",
644                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
645         },
646         {
647                 /*
648                  * ChipsBnk usb stick
649                  * PR: 103702
650                  */
651                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ChipsBnk", "USB*",
652                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
653         },
654         {
655                 /*
656                  * Storcase (Kingston) InfoStation IFS FC2/SATA-R 201A
657                  * PR: 129858
658                  */
659                 {T_DIRECT, SIP_MEDIA_FIXED, "IFS", "FC2/SATA-R*",
660                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
661         },
662         {
663                 /*
664                  * Samsung YP-U3 mp3-player
665                  * PR: 125398
666                  */
667                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Samsung", "YP-U3",
668                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
669         },
670         {
671                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Netac", "OnlyDisk*",
672                  "2000"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
673         },
674         {
675                 /*
676                  * Sony Cyber-Shot DSC cameras
677                  * PR: usb/137035
678                  */
679                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
680                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
681         },
682         {
683                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler G3",
684                  "1.00"}, /*quirks*/ DA_Q_NO_PREVENT
685         },
686         {
687                 /* At least several Transcent USB sticks lie on RC16. */
688                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JetFlash", "Transcend*",
689                  "*"}, /*quirks*/ DA_Q_NO_RC16
690         },
691         /* ATA/SATA devices over SAS/USB/... */
692         {
693                 /* Hitachi Advanced Format (4k) drives */
694                 { T_DIRECT, SIP_MEDIA_FIXED, "Hitachi", "H??????????E3*", "*" },
695                 /*quirks*/DA_Q_4K
696         },
697         {
698                 /* Samsung Advanced Format (4k) drives */
699                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD155UI*", "*" },
700                 /*quirks*/DA_Q_4K
701         },
702         {
703                 /* Samsung Advanced Format (4k) drives */
704                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD155UI*", "*" },
705                 /*quirks*/DA_Q_4K
706         },
707         {
708                 /* Samsung Advanced Format (4k) drives */
709                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD204UI*", "*" },
710                 /*quirks*/DA_Q_4K
711         },
712         {
713                 /* Samsung Advanced Format (4k) drives */
714                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD204UI*", "*" },
715                 /*quirks*/DA_Q_4K
716         },
717         {
718                 /* Seagate Barracuda Green Advanced Format (4k) drives */
719                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DL*", "*" },
720                 /*quirks*/DA_Q_4K
721         },
722         {
723                 /* Seagate Barracuda Green Advanced Format (4k) drives */
724                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DL", "*", "*" },
725                 /*quirks*/DA_Q_4K
726         },
727         {
728                 /* Seagate Barracuda Green Advanced Format (4k) drives */
729                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???DM*", "*" },
730                 /*quirks*/DA_Q_4K
731         },
732         {
733                 /* Seagate Barracuda Green Advanced Format (4k) drives */
734                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???DM*", "*", "*" },
735                 /*quirks*/DA_Q_4K
736         },
737         {
738                 /* Seagate Barracuda Green Advanced Format (4k) drives */
739                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DM*", "*" },
740                 /*quirks*/DA_Q_4K
741         },
742         {
743                 /* Seagate Barracuda Green Advanced Format (4k) drives */
744                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DM", "*", "*" },
745                 /*quirks*/DA_Q_4K
746         },
747         {
748                 /* Seagate Momentus Advanced Format (4k) drives */
749                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500423AS*", "*" },
750                 /*quirks*/DA_Q_4K
751         },
752         {
753                 /* Seagate Momentus Advanced Format (4k) drives */
754                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "3AS*", "*" },
755                 /*quirks*/DA_Q_4K
756         },
757         {
758                 /* Seagate Momentus Advanced Format (4k) drives */
759                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500424AS*", "*" },
760                 /*quirks*/DA_Q_4K
761         },
762         {
763                 /* Seagate Momentus Advanced Format (4k) drives */
764                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "4AS*", "*" },
765                 /*quirks*/DA_Q_4K
766         },
767         {
768                 /* Seagate Momentus Advanced Format (4k) drives */
769                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640423AS*", "*" },
770                 /*quirks*/DA_Q_4K
771         },
772         {
773                 /* Seagate Momentus Advanced Format (4k) drives */
774                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "3AS*", "*" },
775                 /*quirks*/DA_Q_4K
776         },
777         {
778                 /* Seagate Momentus Advanced Format (4k) drives */
779                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640424AS*", "*" },
780                 /*quirks*/DA_Q_4K
781         },
782         {
783                 /* Seagate Momentus Advanced Format (4k) drives */
784                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "4AS*", "*" },
785                 /*quirks*/DA_Q_4K
786         },
787         {
788                 /* Seagate Momentus Advanced Format (4k) drives */
789                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750420AS*", "*" },
790                 /*quirks*/DA_Q_4K
791         },
792         {
793                 /* Seagate Momentus Advanced Format (4k) drives */
794                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "0AS*", "*" },
795                 /*quirks*/DA_Q_4K
796         },
797         {
798                 /* Seagate Momentus Advanced Format (4k) drives */
799                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750422AS*", "*" },
800                 /*quirks*/DA_Q_4K
801         },
802         {
803                 /* Seagate Momentus Advanced Format (4k) drives */
804                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "2AS*", "*" },
805                 /*quirks*/DA_Q_4K
806         },
807         {
808                 /* Seagate Momentus Advanced Format (4k) drives */
809                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750423AS*", "*" },
810                 /*quirks*/DA_Q_4K
811         },
812         {
813                 /* Seagate Momentus Advanced Format (4k) drives */
814                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "3AS*", "*" },
815                 /*quirks*/DA_Q_4K
816         },
817         {
818                 /* Seagate Momentus Thin Advanced Format (4k) drives */
819                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???LT*", "*" },
820                 /*quirks*/DA_Q_4K
821         },
822         {
823                 /* Seagate Momentus Thin Advanced Format (4k) drives */
824                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???LT*", "*", "*" },
825                 /*quirks*/DA_Q_4K
826         },
827         {
828                 /* WDC Caviar Green Advanced Format (4k) drives */
829                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RS*", "*" },
830                 /*quirks*/DA_Q_4K
831         },
832         {
833                 /* WDC Caviar Green Advanced Format (4k) drives */
834                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RS*", "*" },
835                 /*quirks*/DA_Q_4K
836         },
837         {
838                 /* WDC Caviar Green Advanced Format (4k) drives */
839                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RX*", "*" },
840                 /*quirks*/DA_Q_4K
841         },
842         {
843                 /* WDC Caviar Green Advanced Format (4k) drives */
844                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RX*", "*" },
845                 /*quirks*/DA_Q_4K
846         },
847         {
848                 /* WDC Caviar Green Advanced Format (4k) drives */
849                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RS*", "*" },
850                 /*quirks*/DA_Q_4K
851         },
852         {
853                 /* WDC Caviar Green Advanced Format (4k) drives */
854                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RS*", "*" },
855                 /*quirks*/DA_Q_4K
856         },
857         {
858                 /* WDC Caviar Green Advanced Format (4k) drives */
859                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RX*", "*" },
860                 /*quirks*/DA_Q_4K
861         },
862         {
863                 /* WDC Caviar Green Advanced Format (4k) drives */
864                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RX*", "*" },
865                 /*quirks*/DA_Q_4K
866         },
867         {
868                 /* WDC Scorpio Black Advanced Format (4k) drives */
869                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PKT*", "*" },
870                 /*quirks*/DA_Q_4K
871         },
872         {
873                 /* WDC Scorpio Black Advanced Format (4k) drives */
874                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PKT*", "*" },
875                 /*quirks*/DA_Q_4K
876         },
877         {
878                 /* WDC Scorpio Black Advanced Format (4k) drives */
879                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PKT*", "*" },
880                 /*quirks*/DA_Q_4K
881         },
882         {
883                 /* WDC Scorpio Black Advanced Format (4k) drives */
884                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PKT*", "*" },
885                 /*quirks*/DA_Q_4K
886         },
887         {
888                 /* WDC Scorpio Blue Advanced Format (4k) drives */
889                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PVT*", "*" },
890                 /*quirks*/DA_Q_4K
891         },
892         {
893                 /* WDC Scorpio Blue Advanced Format (4k) drives */
894                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PVT*", "*" },
895                 /*quirks*/DA_Q_4K
896         },
897         {
898                 /* WDC Scorpio Blue Advanced Format (4k) drives */
899                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PVT*", "*" },
900                 /*quirks*/DA_Q_4K
901         },
902         {
903                 /* WDC Scorpio Blue Advanced Format (4k) drives */
904                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PVT*", "*" },
905                 /*quirks*/DA_Q_4K
906         },
907         {
908                 /*
909                  * Olympus FE-210 camera
910                  */
911                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "FE210*",
912                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
913         },
914         {
915                 /*
916                  * LG UP3S MP3 player
917                  */
918                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "LG", "UP3S",
919                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
920         },
921         {
922                 /*
923                  * Laser MP3-2GA13 MP3 player
924                  */
925                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "(HS) Flash Disk",
926                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
927         },
928         {
929                 /*
930                  * LaCie external 250GB Hard drive des by Porsche
931                  * Submitted by: Ben Stuyts <ben@altesco.nl>
932                  * PR: 121474
933                  */
934                 {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HM250JI", "*"},
935                 /*quirks*/ DA_Q_NO_SYNC_CACHE
936         },
937         /* SATA SSDs */
938         {
939                 /*
940                  * Corsair Force 2 SSDs
941                  * 4k optimised & trim only works in 4k requests + 4k aligned
942                  */
943                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair CSSD-F*", "*" },
944                 /*quirks*/DA_Q_4K
945         },
946         {
947                 /*
948                  * Corsair Force 3 SSDs
949                  * 4k optimised & trim only works in 4k requests + 4k aligned
950                  */
951                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force 3*", "*" },
952                 /*quirks*/DA_Q_4K
953         },
954         {
955                 /*
956                  * Corsair Force GT SSDs
957                  * 4k optimised & trim only works in 4k requests + 4k aligned
958                  */
959                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "Corsair Force GT*", "*" },
960                 /*quirks*/DA_Q_4K
961         },
962         {
963                 /*
964                  * Crucial M4 SSDs
965                  * 4k optimised & trim only works in 4k requests + 4k aligned
966                  */
967                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "M4-CT???M4SSD2*", "*" },
968                 /*quirks*/DA_Q_4K
969         },
970         {
971                 /*
972                  * Crucial RealSSD C300 SSDs
973                  * 4k optimised
974                  */
975                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "C300-CTFDDAC???MAG*",
976                 "*" }, /*quirks*/DA_Q_4K
977         },
978         {
979                 /*
980                  * Intel 320 Series SSDs
981                  * 4k optimised & trim only works in 4k requests + 4k aligned
982                  */
983                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSA2CW*", "*" },
984                 /*quirks*/DA_Q_4K
985         },
986         {
987                 /*
988                  * Intel 330 Series SSDs
989                  * 4k optimised & trim only works in 4k requests + 4k aligned
990                  */
991                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2CT*", "*" },
992                 /*quirks*/DA_Q_4K
993         },
994         {
995                 /*
996                  * Intel 510 Series SSDs
997                  * 4k optimised & trim only works in 4k requests + 4k aligned
998                  */
999                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2MH*", "*" },
1000                 /*quirks*/DA_Q_4K
1001         },
1002         {
1003                 /*
1004                  * Intel 520 Series SSDs
1005                  * 4k optimised & trim only works in 4k requests + 4k aligned
1006                  */
1007                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "INTEL SSDSC2BW*", "*" },
1008                 /*quirks*/DA_Q_4K
1009         },
1010         {
1011                 /*
1012                  * Kingston E100 Series SSDs
1013                  * 4k optimised & trim only works in 4k requests + 4k aligned
1014                  */
1015                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SE100S3*", "*" },
1016                 /*quirks*/DA_Q_4K
1017         },
1018         {
1019                 /*
1020                  * Kingston HyperX 3k SSDs
1021                  * 4k optimised & trim only works in 4k requests + 4k aligned
1022                  */
1023                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "KINGSTON SH103S3*", "*" },
1024                 /*quirks*/DA_Q_4K
1025         },
1026         {
1027                 /*
1028                  * OCZ Agility 3 SSDs
1029                  * 4k optimised & trim only works in 4k requests + 4k aligned
1030                  */
1031                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-AGILITY3*", "*" },
1032                 /*quirks*/DA_Q_4K
1033         },
1034         {
1035                 /*
1036                  * OCZ Deneva R Series SSDs
1037                  * 4k optimised & trim only works in 4k requests + 4k aligned
1038                  */
1039                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "DENRSTE251M45*", "*" },
1040                 /*quirks*/DA_Q_4K
1041         },
1042         {
1043                 /*
1044                  * OCZ Vertex 2 SSDs (inc pro series)
1045                  * 4k optimised & trim only works in 4k requests + 4k aligned
1046                  */
1047                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ?VERTEX2*", "*" },
1048                 /*quirks*/DA_Q_4K
1049         },
1050         {
1051                 /*
1052                  * OCZ Vertex 3 SSDs
1053                  * 4k optimised & trim only works in 4k requests + 4k aligned
1054                  */
1055                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX3*", "*" },
1056                 /*quirks*/DA_Q_4K
1057         },
1058         {
1059                 /*
1060                  * OCZ Vertex 4 SSDs
1061                  * 4k optimised & trim only works in 4k requests + 4k aligned
1062                  */
1063                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "OCZ-VERTEX4*", "*" },
1064                 /*quirks*/DA_Q_4K
1065         },
1066         {
1067                 /*
1068                  * Samsung 830 Series SSDs
1069                  * 4k optimised & trim only works in 4k requests + 4k aligned
1070                  */
1071                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG SSD 830 Series*", "*" },
1072                 /*quirks*/DA_Q_4K
1073         },
1074         {
1075                 /*
1076                  * SuperTalent TeraDrive CT SSDs
1077                  * 4k optimised & trim only works in 4k requests + 4k aligned
1078                  */
1079                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "FTM??CT25H*", "*" },
1080                 /*quirks*/DA_Q_4K
1081         },
1082         {
1083                 /*
1084                  * XceedIOPS SATA SSDs
1085                  * 4k optimised
1086                  */
1087                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SG9XCS2D*", "*" },
1088                 /*quirks*/DA_Q_4K
1089         },
1090 };
1091
1092 static  disk_strategy_t dastrategy;
1093 static  dumper_t        dadump;
1094 static  periph_init_t   dainit;
1095 static  void            daasync(void *callback_arg, u_int32_t code,
1096                                 struct cam_path *path, void *arg);
1097 static  void            dasysctlinit(void *context, int pending);
1098 static  int             dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
1099 static  int             dadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
1100 static  int             dadeletemaxsysctl(SYSCTL_HANDLER_ARGS);
1101 static  void            dadeletemethodset(struct da_softc *softc,
1102                                           da_delete_methods delete_method);
1103 static  off_t           dadeletemaxsize(struct da_softc *softc,
1104                                         da_delete_methods delete_method);
1105 static  void            dadeletemethodchoose(struct da_softc *softc,
1106                                              da_delete_methods default_method);
1107 static  void            daprobedone(struct cam_periph *periph, union ccb *ccb);
1108
1109 static  periph_ctor_t   daregister;
1110 static  periph_dtor_t   dacleanup;
1111 static  periph_start_t  dastart;
1112 static  periph_oninv_t  daoninvalidate;
1113 static  void            dadone(struct cam_periph *periph,
1114                                union ccb *done_ccb);
1115 static  int             daerror(union ccb *ccb, u_int32_t cam_flags,
1116                                 u_int32_t sense_flags);
1117 static void             daprevent(struct cam_periph *periph, int action);
1118 static void             dareprobe(struct cam_periph *periph);
1119 static void             dasetgeom(struct cam_periph *periph, uint32_t block_len,
1120                                   uint64_t maxsector,
1121                                   struct scsi_read_capacity_data_long *rcaplong,
1122                                   size_t rcap_size);
1123 static timeout_t        dasendorderedtag;
1124 static void             dashutdown(void *arg, int howto);
1125 static timeout_t        damediapoll;
1126
1127 #ifndef DA_DEFAULT_POLL_PERIOD
1128 #define DA_DEFAULT_POLL_PERIOD  3
1129 #endif
1130
1131 #ifndef DA_DEFAULT_TIMEOUT
1132 #define DA_DEFAULT_TIMEOUT 60   /* Timeout in seconds */
1133 #endif
1134
1135 #ifndef DA_DEFAULT_RETRY
1136 #define DA_DEFAULT_RETRY        4
1137 #endif
1138
1139 #ifndef DA_DEFAULT_SEND_ORDERED
1140 #define DA_DEFAULT_SEND_ORDERED 1
1141 #endif
1142
1143 #define DA_SIO (softc->sort_io_queue >= 0 ? \
1144     softc->sort_io_queue : cam_sort_io_queues)
1145
1146 static int da_poll_period = DA_DEFAULT_POLL_PERIOD;
1147 static int da_retry_count = DA_DEFAULT_RETRY;
1148 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
1149 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
1150
1151 static SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
1152             "CAM Direct Access Disk driver");
1153 SYSCTL_INT(_kern_cam_da, OID_AUTO, poll_period, CTLFLAG_RW,
1154            &da_poll_period, 0, "Media polling period in seconds");
1155 TUNABLE_INT("kern.cam.da.poll_period", &da_poll_period);
1156 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
1157            &da_retry_count, 0, "Normal I/O retry count");
1158 TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
1159 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
1160            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
1161 TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
1162 SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFLAG_RW,
1163            &da_send_ordered, 0, "Send Ordered Tags");
1164 TUNABLE_INT("kern.cam.da.send_ordered", &da_send_ordered);
1165
1166 /*
1167  * DA_ORDEREDTAG_INTERVAL determines how often, relative
1168  * to the default timeout, we check to see whether an ordered
1169  * tagged transaction is appropriate to prevent simple tag
1170  * starvation.  Since we'd like to ensure that there is at least
1171  * 1/2 of the timeout length left for a starved transaction to
1172  * complete after we've sent an ordered tag, we must poll at least
1173  * four times in every timeout period.  This takes care of the worst
1174  * case where a starved transaction starts during an interval that
1175  * meets the requirement "don't send an ordered tag" test so it takes
1176  * us two intervals to determine that a tag must be sent.
1177  */
1178 #ifndef DA_ORDEREDTAG_INTERVAL
1179 #define DA_ORDEREDTAG_INTERVAL 4
1180 #endif
1181
1182 static struct periph_driver dadriver =
1183 {
1184         dainit, "da",
1185         TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
1186 };
1187
1188 PERIPHDRIVER_DECLARE(da, dadriver);
1189
1190 static MALLOC_DEFINE(M_SCSIDA, "scsi_da", "scsi_da buffers");
1191
1192 static int
1193 daopen(struct disk *dp)
1194 {
1195         struct cam_periph *periph;
1196         struct da_softc *softc;
1197         int error;
1198
1199         periph = (struct cam_periph *)dp->d_drv1;
1200         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
1201                 return (ENXIO);
1202         }
1203
1204         cam_periph_lock(periph);
1205         if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
1206                 cam_periph_unlock(periph);
1207                 cam_periph_release(periph);
1208                 return (error);
1209         }
1210
1211         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1212             ("daopen\n"));
1213
1214         softc = (struct da_softc *)periph->softc;
1215         softc->flags |= DA_FLAG_OPEN;
1216         softc->flags &= ~DA_FLAG_PACK_INVALID;
1217
1218         dareprobe(periph);
1219
1220         /* Wait for the disk size update.  */
1221         error = cam_periph_sleep(periph, &softc->disk->d_mediasize, PRIBIO,
1222             "dareprobe", 0);
1223         if (error != 0)
1224                 xpt_print(periph->path, "unable to retrieve capacity data");
1225
1226         if (periph->flags & CAM_PERIPH_INVALID ||
1227             softc->disk->d_sectorsize == 0 ||
1228             softc->disk->d_mediasize == 0)
1229                 error = ENXIO;
1230
1231         if (error == 0 && (softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
1232             (softc->quirks & DA_Q_NO_PREVENT) == 0)
1233                 daprevent(periph, PR_PREVENT);
1234
1235         if (error == 0)
1236                 softc->flags |= DA_FLAG_SAW_MEDIA;
1237
1238         cam_periph_unhold(periph);
1239         cam_periph_unlock(periph);
1240
1241         if (error != 0) {
1242                 softc->flags &= ~DA_FLAG_OPEN;
1243                 cam_periph_release(periph);
1244         }
1245
1246         return (error);
1247 }
1248
1249 static int
1250 daclose(struct disk *dp)
1251 {
1252         struct  cam_periph *periph;
1253         struct  da_softc *softc;
1254         int error;
1255
1256         periph = (struct cam_periph *)dp->d_drv1;
1257         cam_periph_lock(periph);
1258         if (cam_periph_hold(periph, PRIBIO) != 0) {
1259                 cam_periph_unlock(periph);
1260                 cam_periph_release(periph);
1261                 return (0);
1262         }
1263
1264         softc = (struct da_softc *)periph->softc;
1265
1266         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1267             ("daclose\n"));
1268
1269         if ((softc->flags & DA_FLAG_DIRTY) != 0 &&
1270             (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 &&
1271             (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
1272                 union   ccb *ccb;
1273
1274                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1275
1276                 scsi_synchronize_cache(&ccb->csio,
1277                                        /*retries*/1,
1278                                        /*cbfcnp*/dadone,
1279                                        MSG_SIMPLE_Q_TAG,
1280                                        /*begin_lba*/0,/* Cover the whole disk */
1281                                        /*lb_count*/0,
1282                                        SSD_FULL_SIZE,
1283                                        5 * 60 * 1000);
1284
1285                 error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
1286                                   /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
1287                                   softc->disk->d_devstat);
1288                 if (error == 0)
1289                         softc->flags &= ~DA_FLAG_DIRTY;
1290                 xpt_release_ccb(ccb);
1291
1292         }
1293
1294         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
1295                 if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
1296                         daprevent(periph, PR_ALLOW);
1297                 /*
1298                  * If we've got removeable media, mark the blocksize as
1299                  * unavailable, since it could change when new media is
1300                  * inserted.
1301                  */
1302                 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
1303         }
1304
1305         softc->flags &= ~DA_FLAG_OPEN;
1306         cam_periph_unhold(periph);
1307         cam_periph_unlock(periph);
1308         cam_periph_release(periph);
1309         return (0);     
1310 }
1311
1312 static void
1313 daschedule(struct cam_periph *periph)
1314 {
1315         struct da_softc *softc = (struct da_softc *)periph->softc;
1316         uint32_t prio;
1317
1318         if (softc->state != DA_STATE_NORMAL)
1319                 return;
1320
1321         /* Check if cam_periph_getccb() was called. */
1322         prio = periph->immediate_priority;
1323
1324         /* Check if we have more work to do. */
1325         if (bioq_first(&softc->bio_queue) ||
1326             (!softc->delete_running && bioq_first(&softc->delete_queue)) ||
1327             softc->tur) {
1328                 prio = CAM_PRIORITY_NORMAL;
1329         }
1330
1331         /* Schedule CCB if any of above is true. */
1332         if (prio != CAM_PRIORITY_NONE)
1333                 xpt_schedule(periph, prio);
1334 }
1335
1336 /*
1337  * Actually translate the requested transfer into one the physical driver
1338  * can understand.  The transfer is described by a buf and will include
1339  * only one physical transfer.
1340  */
1341 static void
1342 dastrategy(struct bio *bp)
1343 {
1344         struct cam_periph *periph;
1345         struct da_softc *softc;
1346         
1347         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1348         softc = (struct da_softc *)periph->softc;
1349
1350         cam_periph_lock(periph);
1351
1352         /*
1353          * If the device has been made invalid, error out
1354          */
1355         if ((softc->flags & DA_FLAG_PACK_INVALID)) {
1356                 cam_periph_unlock(periph);
1357                 biofinish(bp, NULL, ENXIO);
1358                 return;
1359         }
1360
1361         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastrategy(%p)\n", bp));
1362
1363         /*
1364          * Place it in the queue of disk activities for this disk
1365          */
1366         if (bp->bio_cmd == BIO_DELETE) {
1367                 if (bp->bio_bcount == 0)
1368                         biodone(bp);
1369                 else if (DA_SIO)
1370                         bioq_disksort(&softc->delete_queue, bp);
1371                 else
1372                         bioq_insert_tail(&softc->delete_queue, bp);
1373         } else if (DA_SIO) {
1374                 bioq_disksort(&softc->bio_queue, bp);
1375         } else {
1376                 bioq_insert_tail(&softc->bio_queue, bp);
1377         }
1378
1379         /*
1380          * Schedule ourselves for performing the work.
1381          */
1382         daschedule(periph);
1383         cam_periph_unlock(periph);
1384
1385         return;
1386 }
1387
1388 static int
1389 dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
1390 {
1391         struct      cam_periph *periph;
1392         struct      da_softc *softc;
1393         u_int       secsize;
1394         struct      ccb_scsiio csio;
1395         struct      disk *dp;
1396         int         error = 0;
1397
1398         dp = arg;
1399         periph = dp->d_drv1;
1400         softc = (struct da_softc *)periph->softc;
1401         cam_periph_lock(periph);
1402         secsize = softc->params.secsize;
1403         
1404         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
1405                 cam_periph_unlock(periph);
1406                 return (ENXIO);
1407         }
1408
1409         if (length > 0) {
1410                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1411                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
1412                 scsi_read_write(&csio,
1413                                 /*retries*/0,
1414                                 dadone,
1415                                 MSG_ORDERED_Q_TAG,
1416                                 /*read*/SCSI_RW_WRITE,
1417                                 /*byte2*/0,
1418                                 /*minimum_cmd_size*/ softc->minimum_cmd_size,
1419                                 offset / secsize,
1420                                 length / secsize,
1421                                 /*data_ptr*/(u_int8_t *) virtual,
1422                                 /*dxfer_len*/length,
1423                                 /*sense_len*/SSD_FULL_SIZE,
1424                                 da_default_timeout * 1000);
1425                 xpt_polled_action((union ccb *)&csio);
1426
1427                 error = cam_periph_error((union ccb *)&csio,
1428                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1429                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
1430                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
1431                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
1432                 if (error != 0)
1433                         printf("Aborting dump due to I/O error.\n");
1434                 cam_periph_unlock(periph);
1435                 return (error);
1436         }
1437                 
1438         /*
1439          * Sync the disk cache contents to the physical media.
1440          */
1441         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
1442
1443                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1444                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
1445                 scsi_synchronize_cache(&csio,
1446                                        /*retries*/0,
1447                                        /*cbfcnp*/dadone,
1448                                        MSG_SIMPLE_Q_TAG,
1449                                        /*begin_lba*/0,/* Cover the whole disk */
1450                                        /*lb_count*/0,
1451                                        SSD_FULL_SIZE,
1452                                        5 * 60 * 1000);
1453                 xpt_polled_action((union ccb *)&csio);
1454
1455                 error = cam_periph_error((union ccb *)&csio,
1456                     0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
1457                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
1458                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
1459                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
1460                 if (error != 0)
1461                         xpt_print(periph->path, "Synchronize cache failed\n");
1462         }
1463         cam_periph_unlock(periph);
1464         return (error);
1465 }
1466
1467 static int
1468 dagetattr(struct bio *bp)
1469 {
1470         int ret;
1471         struct cam_periph *periph;
1472
1473         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1474         cam_periph_lock(periph);
1475         ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
1476             periph->path);
1477         cam_periph_unlock(periph);
1478         if (ret == 0)
1479                 bp->bio_completed = bp->bio_length;
1480         return ret;
1481 }
1482
1483 static void
1484 dainit(void)
1485 {
1486         cam_status status;
1487
1488         /*
1489          * Install a global async callback.  This callback will
1490          * receive async callbacks like "new device found".
1491          */
1492         status = xpt_register_async(AC_FOUND_DEVICE, daasync, NULL, NULL);
1493
1494         if (status != CAM_REQ_CMP) {
1495                 printf("da: Failed to attach master async callback "
1496                        "due to status 0x%x!\n", status);
1497         } else if (da_send_ordered) {
1498
1499                 /* Register our shutdown event handler */
1500                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 
1501                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
1502                     printf("dainit: shutdown event registration failed!\n");
1503         }
1504 }
1505
1506 /*
1507  * Callback from GEOM, called when it has finished cleaning up its
1508  * resources.
1509  */
1510 static void
1511 dadiskgonecb(struct disk *dp)
1512 {
1513         struct cam_periph *periph;
1514
1515         periph = (struct cam_periph *)dp->d_drv1;
1516         cam_periph_release(periph);
1517 }
1518
1519 static void
1520 daoninvalidate(struct cam_periph *periph)
1521 {
1522         struct da_softc *softc;
1523
1524         softc = (struct da_softc *)periph->softc;
1525
1526         /*
1527          * De-register any async callbacks.
1528          */
1529         xpt_register_async(0, daasync, periph, periph->path);
1530
1531         softc->flags |= DA_FLAG_PACK_INVALID;
1532
1533         /*
1534          * Return all queued I/O with ENXIO.
1535          * XXX Handle any transactions queued to the card
1536          *     with XPT_ABORT_CCB.
1537          */
1538         bioq_flush(&softc->bio_queue, NULL, ENXIO);
1539         bioq_flush(&softc->delete_queue, NULL, ENXIO);
1540
1541         /*
1542          * Tell GEOM that we've gone away, we'll get a callback when it is
1543          * done cleaning up its resources.
1544          */
1545         disk_gone(softc->disk);
1546
1547         xpt_print(periph->path, "lost device - %d outstanding, %d refs\n",
1548                   softc->outstanding_cmds, periph->refcount);
1549 }
1550
1551 static void
1552 dacleanup(struct cam_periph *periph)
1553 {
1554         struct da_softc *softc;
1555
1556         softc = (struct da_softc *)periph->softc;
1557
1558         xpt_print(periph->path, "removing device entry\n");
1559         cam_periph_unlock(periph);
1560
1561         /*
1562          * If we can't free the sysctl tree, oh well...
1563          */
1564         if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
1565             && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
1566                 xpt_print(periph->path, "can't remove sysctl context\n");
1567         }
1568
1569         callout_drain(&softc->mediapoll_c);
1570         disk_destroy(softc->disk);
1571         callout_drain(&softc->sendordered_c);
1572         free(softc, M_DEVBUF);
1573         cam_periph_lock(periph);
1574 }
1575
1576 static void
1577 daasync(void *callback_arg, u_int32_t code,
1578         struct cam_path *path, void *arg)
1579 {
1580         struct cam_periph *periph;
1581         struct da_softc *softc;
1582
1583         periph = (struct cam_periph *)callback_arg;
1584         switch (code) {
1585         case AC_FOUND_DEVICE:
1586         {
1587                 struct ccb_getdev *cgd;
1588                 cam_status status;
1589  
1590                 cgd = (struct ccb_getdev *)arg;
1591                 if (cgd == NULL)
1592                         break;
1593
1594                 if (cgd->protocol != PROTO_SCSI)
1595                         break;
1596
1597                 if (SID_TYPE(&cgd->inq_data) != T_DIRECT
1598                     && SID_TYPE(&cgd->inq_data) != T_RBC
1599                     && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
1600                         break;
1601
1602                 /*
1603                  * Allocate a peripheral instance for
1604                  * this device and start the probe
1605                  * process.
1606                  */
1607                 status = cam_periph_alloc(daregister, daoninvalidate,
1608                                           dacleanup, dastart,
1609                                           "da", CAM_PERIPH_BIO,
1610                                           cgd->ccb_h.path, daasync,
1611                                           AC_FOUND_DEVICE, cgd);
1612
1613                 if (status != CAM_REQ_CMP
1614                  && status != CAM_REQ_INPROG)
1615                         printf("daasync: Unable to attach to new device "
1616                                 "due to status 0x%x\n", status);
1617                 return;
1618         }
1619         case AC_ADVINFO_CHANGED:
1620         {
1621                 uintptr_t buftype;
1622
1623                 buftype = (uintptr_t)arg;
1624                 if (buftype == CDAI_TYPE_PHYS_PATH) {
1625                         struct da_softc *softc;
1626
1627                         softc = periph->softc;
1628                         disk_attr_changed(softc->disk, "GEOM::physpath",
1629                                           M_NOWAIT);
1630                 }
1631                 break;
1632         }
1633         case AC_UNIT_ATTENTION:
1634         {
1635                 union ccb *ccb;
1636                 int error_code, sense_key, asc, ascq;
1637
1638                 softc = (struct da_softc *)periph->softc;
1639                 ccb = (union ccb *)arg;
1640
1641                 /*
1642                  * Handle all UNIT ATTENTIONs except our own,
1643                  * as they will be handled by daerror().
1644                  */
1645                 if (xpt_path_periph(ccb->ccb_h.path) != periph &&
1646                     scsi_extract_sense_ccb(ccb,
1647                      &error_code, &sense_key, &asc, &ascq)) {
1648                         if (asc == 0x2A && ascq == 0x09) {
1649                                 xpt_print(ccb->ccb_h.path,
1650                                     "capacity data has changed\n");
1651                                 dareprobe(periph);
1652                         } else if (asc == 0x28 && ascq == 0x00)
1653                                 disk_media_changed(softc->disk, M_NOWAIT);
1654                 }
1655                 cam_periph_async(periph, code, path, arg);
1656                 break;
1657         }
1658         case AC_SCSI_AEN:
1659                 softc = (struct da_softc *)periph->softc;
1660                 if (!softc->tur) {
1661                         if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
1662                                 softc->tur = 1;
1663                                 daschedule(periph);
1664                         }
1665                 }
1666                 /* FALLTHROUGH */
1667         case AC_SENT_BDR:
1668         case AC_BUS_RESET:
1669         {
1670                 struct ccb_hdr *ccbh;
1671
1672                 softc = (struct da_softc *)periph->softc;
1673                 /*
1674                  * Don't fail on the expected unit attention
1675                  * that will occur.
1676                  */
1677                 softc->flags |= DA_FLAG_RETRY_UA;
1678                 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
1679                         ccbh->ccb_state |= DA_CCB_RETRY_UA;
1680                 break;
1681         }
1682         default:
1683                 break;
1684         }
1685         cam_periph_async(periph, code, path, arg);
1686 }
1687
1688 static void
1689 dasysctlinit(void *context, int pending)
1690 {
1691         struct cam_periph *periph;
1692         struct da_softc *softc;
1693         char tmpstr[80], tmpstr2[80];
1694         struct ccb_trans_settings cts;
1695
1696         periph = (struct cam_periph *)context;
1697         /*
1698          * periph was held for us when this task was enqueued
1699          */
1700         if (periph->flags & CAM_PERIPH_INVALID) {
1701                 cam_periph_release(periph);
1702                 return;
1703         }
1704
1705         softc = (struct da_softc *)periph->softc;
1706         snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
1707         snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
1708
1709         sysctl_ctx_init(&softc->sysctl_ctx);
1710         softc->flags |= DA_FLAG_SCTX_INIT;
1711         softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
1712                 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
1713                 CTLFLAG_RD, 0, tmpstr);
1714         if (softc->sysctl_tree == NULL) {
1715                 printf("dasysctlinit: unable to allocate sysctl tree\n");
1716                 cam_periph_release(periph);
1717                 return;
1718         }
1719
1720         /*
1721          * Now register the sysctl handler, so the user can change the value on
1722          * the fly.
1723          */
1724         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1725                 OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
1726                 softc, 0, dadeletemethodsysctl, "A",
1727                 "BIO_DELETE execution method");
1728         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1729                 OID_AUTO, "delete_max", CTLTYPE_U64 | CTLFLAG_RW,
1730                 softc, 0, dadeletemaxsysctl, "Q",
1731                 "Maximum BIO_DELETE size");
1732         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1733                 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
1734                 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
1735                 "Minimum CDB size");
1736         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1737                 OID_AUTO, "sort_io_queue", CTLFLAG_RW, &softc->sort_io_queue, 0,
1738                 "Sort IO queue to try and optimise disk access patterns");
1739
1740         SYSCTL_ADD_INT(&softc->sysctl_ctx,
1741                        SYSCTL_CHILDREN(softc->sysctl_tree),
1742                        OID_AUTO,
1743                        "error_inject",
1744                        CTLFLAG_RW,
1745                        &softc->error_inject,
1746                        0,
1747                        "error_inject leaf");
1748
1749
1750         /*
1751          * Add some addressing info.
1752          */
1753         memset(&cts, 0, sizeof (cts));
1754         xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
1755         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1756         cts.type = CTS_TYPE_CURRENT_SETTINGS;
1757         cam_periph_lock(periph);
1758         xpt_action((union ccb *)&cts);
1759         cam_periph_unlock(periph);
1760         if (cts.ccb_h.status != CAM_REQ_CMP) {
1761                 cam_periph_release(periph);
1762                 return;
1763         }
1764         if (cts.protocol == PROTO_SCSI && cts.transport == XPORT_FC) {
1765                 struct ccb_trans_settings_fc *fc = &cts.xport_specific.fc;
1766                 if (fc->valid & CTS_FC_VALID_WWPN) {
1767                         softc->wwpn = fc->wwpn;
1768                         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1769                             SYSCTL_CHILDREN(softc->sysctl_tree),
1770                             OID_AUTO, "wwpn", CTLFLAG_RD,
1771                             &softc->wwpn, "World Wide Port Name");
1772                 }
1773         }
1774         cam_periph_release(periph);
1775 }
1776
1777 static int
1778 dadeletemaxsysctl(SYSCTL_HANDLER_ARGS)
1779 {
1780         int error;
1781         uint64_t value;
1782         struct da_softc *softc;
1783
1784         softc = (struct da_softc *)arg1;
1785
1786         value = softc->disk->d_delmaxsize;
1787         error = sysctl_handle_64(oidp, &value, 0, req);
1788         if ((error != 0) || (req->newptr == NULL))
1789                 return (error);
1790
1791         /* only accept values smaller than the calculated value */
1792         if (value > dadeletemaxsize(softc, softc->delete_method)) {
1793                 return (EINVAL);
1794         }
1795         softc->disk->d_delmaxsize = value;
1796
1797         return (0);
1798 }
1799
1800 static int
1801 dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
1802 {
1803         int error, value;
1804
1805         value = *(int *)arg1;
1806
1807         error = sysctl_handle_int(oidp, &value, 0, req);
1808
1809         if ((error != 0)
1810          || (req->newptr == NULL))
1811                 return (error);
1812
1813         /*
1814          * Acceptable values here are 6, 10, 12 or 16.
1815          */
1816         if (value < 6)
1817                 value = 6;
1818         else if ((value > 6)
1819               && (value <= 10))
1820                 value = 10;
1821         else if ((value > 10)
1822               && (value <= 12))
1823                 value = 12;
1824         else if (value > 12)
1825                 value = 16;
1826
1827         *(int *)arg1 = value;
1828
1829         return (0);
1830 }
1831
1832 static void
1833 dadeletemethodset(struct da_softc *softc, da_delete_methods delete_method)
1834 {
1835
1836
1837         softc->delete_method = delete_method;
1838         softc->disk->d_delmaxsize = dadeletemaxsize(softc, delete_method);
1839         softc->delete_func = da_delete_functions[delete_method];
1840
1841         if (softc->delete_method > DA_DELETE_DISABLE)
1842                 softc->disk->d_flags |= DISKFLAG_CANDELETE;
1843         else
1844                 softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
1845 }
1846
1847 static off_t
1848 dadeletemaxsize(struct da_softc *softc, da_delete_methods delete_method)
1849 {
1850         off_t sectors;
1851
1852         switch(delete_method) {
1853         case DA_DELETE_UNMAP:
1854                 sectors = (off_t)softc->unmap_max_lba * softc->unmap_max_ranges;
1855                 break;
1856         case DA_DELETE_ATA_TRIM:
1857                 sectors = (off_t)ATA_DSM_RANGE_MAX * softc->trim_max_ranges;
1858                 break;
1859         case DA_DELETE_WS16:
1860                 sectors = (off_t)min(softc->ws_max_blks, WS16_MAX_BLKS);
1861                 break;
1862         case DA_DELETE_ZERO:
1863         case DA_DELETE_WS10:
1864                 sectors = (off_t)min(softc->ws_max_blks, WS10_MAX_BLKS);
1865                 break;
1866         default:
1867                 return 0;
1868         }
1869
1870         return (off_t)softc->params.secsize *
1871             min(sectors, (off_t)softc->params.sectors);
1872 }
1873
1874 static void
1875 daprobedone(struct cam_periph *periph, union ccb *ccb)
1876 {
1877         struct da_softc *softc;
1878
1879         softc = (struct da_softc *)periph->softc;
1880
1881         dadeletemethodchoose(softc, DA_DELETE_NONE);
1882
1883         if (bootverbose && (softc->flags & DA_FLAG_PROBED) == 0) {
1884                 char buf[80];
1885                 int i, sep;
1886
1887                 snprintf(buf, sizeof(buf), "Delete methods: <");
1888                 sep = 0;
1889                 for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
1890                         if (softc->delete_available & (1 << i)) {
1891                                 if (sep) {
1892                                         strlcat(buf, ",", sizeof(buf));
1893                                 } else {
1894                                     sep = 1;
1895                                 }
1896                                 strlcat(buf, da_delete_method_names[i],
1897                                     sizeof(buf));
1898                                 if (i == softc->delete_method) {
1899                                         strlcat(buf, "(*)", sizeof(buf));
1900                                 }
1901                         }
1902                 }
1903                 if (sep == 0) {
1904                         if (softc->delete_method == DA_DELETE_NONE) 
1905                                 strlcat(buf, "NONE(*)", sizeof(buf));
1906                         else
1907                                 strlcat(buf, "DISABLED(*)", sizeof(buf));
1908                 }
1909                 strlcat(buf, ">", sizeof(buf));
1910                 printf("%s%d: %s\n", periph->periph_name,
1911                     periph->unit_number, buf);
1912         }
1913
1914         /*
1915          * Since our peripheral may be invalidated by an error
1916          * above or an external event, we must release our CCB
1917          * before releasing the probe lock on the peripheral.
1918          * The peripheral will only go away once the last lock
1919          * is removed, and we need it around for the CCB release
1920          * operation.
1921          */
1922         xpt_release_ccb(ccb);
1923         softc->state = DA_STATE_NORMAL;
1924         daschedule(periph);
1925         wakeup(&softc->disk->d_mediasize);
1926         if ((softc->flags & DA_FLAG_PROBED) == 0) {
1927                 softc->flags |= DA_FLAG_PROBED;
1928                 cam_periph_unhold(periph);
1929         } else
1930                 cam_periph_release_locked(periph);
1931 }
1932
1933 static void
1934 dadeletemethodchoose(struct da_softc *softc, da_delete_methods default_method)
1935 {
1936         int i, delete_method;
1937
1938         delete_method = default_method;
1939
1940         /*
1941          * Use the pre-defined order to choose the best
1942          * performing delete.
1943          */
1944         for (i = DA_DELETE_MIN; i <= DA_DELETE_MAX; i++) {
1945                 if (softc->delete_available & (1 << i)) {
1946                         dadeletemethodset(softc, i);
1947                         return;
1948                 }
1949         }
1950         dadeletemethodset(softc, delete_method);
1951 }
1952
1953 static int
1954 dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
1955 {
1956         char buf[16];
1957         const char *p;
1958         struct da_softc *softc;
1959         int i, error, value;
1960
1961         softc = (struct da_softc *)arg1;
1962
1963         value = softc->delete_method;
1964         if (value < 0 || value > DA_DELETE_MAX)
1965                 p = "UNKNOWN";
1966         else
1967                 p = da_delete_method_names[value];
1968         strncpy(buf, p, sizeof(buf));
1969         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
1970         if (error != 0 || req->newptr == NULL)
1971                 return (error);
1972         for (i = 0; i <= DA_DELETE_MAX; i++) {
1973                 if (!(softc->delete_available & (1 << i)) ||
1974                     strcmp(buf, da_delete_method_names[i]) != 0)
1975                         continue;
1976                 dadeletemethodset(softc, i);
1977                 return (0);
1978         }
1979         return (EINVAL);
1980 }
1981
1982 static cam_status
1983 daregister(struct cam_periph *periph, void *arg)
1984 {
1985         struct da_softc *softc;
1986         struct ccb_pathinq cpi;
1987         struct ccb_getdev *cgd;
1988         char tmpstr[80];
1989         caddr_t match;
1990
1991         cgd = (struct ccb_getdev *)arg;
1992         if (cgd == NULL) {
1993                 printf("daregister: no getdev CCB, can't register device\n");
1994                 return(CAM_REQ_CMP_ERR);
1995         }
1996
1997         softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
1998             M_NOWAIT|M_ZERO);
1999
2000         if (softc == NULL) {
2001                 printf("daregister: Unable to probe new device. "
2002                        "Unable to allocate softc\n");                           
2003                 return(CAM_REQ_CMP_ERR);
2004         }
2005
2006         LIST_INIT(&softc->pending_ccbs);
2007         softc->state = DA_STATE_PROBE_RC;
2008         bioq_init(&softc->bio_queue);
2009         bioq_init(&softc->delete_queue);
2010         bioq_init(&softc->delete_run_queue);
2011         if (SID_IS_REMOVABLE(&cgd->inq_data))
2012                 softc->flags |= DA_FLAG_PACK_REMOVABLE;
2013         softc->unmap_max_ranges = UNMAP_MAX_RANGES;
2014         softc->unmap_max_lba = UNMAP_RANGE_MAX;
2015         softc->ws_max_blks = WS16_MAX_BLKS;
2016         softc->trim_max_ranges = ATA_TRIM_MAX_RANGES;
2017         softc->sort_io_queue = -1;
2018
2019         periph->softc = softc;
2020
2021         /*
2022          * See if this device has any quirks.
2023          */
2024         match = cam_quirkmatch((caddr_t)&cgd->inq_data,
2025                                (caddr_t)da_quirk_table,
2026                                sizeof(da_quirk_table)/sizeof(*da_quirk_table),
2027                                sizeof(*da_quirk_table), scsi_inquiry_match);
2028
2029         if (match != NULL)
2030                 softc->quirks = ((struct da_quirk_entry *)match)->quirks;
2031         else
2032                 softc->quirks = DA_Q_NONE;
2033
2034         /* Check if the SIM does not want 6 byte commands */
2035         bzero(&cpi, sizeof(cpi));
2036         xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
2037         cpi.ccb_h.func_code = XPT_PATH_INQ;
2038         xpt_action((union ccb *)&cpi);
2039         if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
2040                 softc->quirks |= DA_Q_NO_6_BYTE;
2041
2042         TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
2043
2044         /*
2045          * Take an exclusive refcount on the periph while dastart is called
2046          * to finish the probe.  The reference will be dropped in dadone at
2047          * the end of probe.
2048          */
2049         (void)cam_periph_hold(periph, PRIBIO);
2050
2051         /*
2052          * Schedule a periodic event to occasionally send an
2053          * ordered tag to a device.
2054          */
2055         callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
2056         callout_reset(&softc->sendordered_c,
2057             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
2058             dasendorderedtag, softc);
2059
2060         cam_periph_unlock(periph);
2061         /*
2062          * RBC devices don't have to support READ(6), only READ(10).
2063          */
2064         if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
2065                 softc->minimum_cmd_size = 10;
2066         else
2067                 softc->minimum_cmd_size = 6;
2068
2069         /*
2070          * Load the user's default, if any.
2071          */
2072         snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
2073                  periph->unit_number);
2074         TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
2075
2076         /*
2077          * 6, 10, 12 and 16 are the currently permissible values.
2078          */
2079         if (softc->minimum_cmd_size < 6)
2080                 softc->minimum_cmd_size = 6;
2081         else if ((softc->minimum_cmd_size > 6)
2082               && (softc->minimum_cmd_size <= 10))
2083                 softc->minimum_cmd_size = 10;
2084         else if ((softc->minimum_cmd_size > 10)
2085               && (softc->minimum_cmd_size <= 12))
2086                 softc->minimum_cmd_size = 12;
2087         else if (softc->minimum_cmd_size > 12)
2088                 softc->minimum_cmd_size = 16;
2089
2090         /* Predict whether device may support READ CAPACITY(16). */
2091         if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC3 &&
2092             (softc->quirks & DA_Q_NO_RC16) == 0) {
2093                 softc->flags |= DA_FLAG_CAN_RC16;
2094                 softc->state = DA_STATE_PROBE_RC16;
2095         }
2096
2097         /*
2098          * Register this media as a disk.
2099          */
2100         softc->disk = disk_alloc();
2101         softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
2102                           periph->unit_number, 0,
2103                           DEVSTAT_BS_UNAVAILABLE,
2104                           SID_TYPE(&cgd->inq_data) |
2105                           XPORT_DEVSTAT_TYPE(cpi.transport),
2106                           DEVSTAT_PRIORITY_DISK);
2107         softc->disk->d_open = daopen;
2108         softc->disk->d_close = daclose;
2109         softc->disk->d_strategy = dastrategy;
2110         softc->disk->d_dump = dadump;
2111         softc->disk->d_getattr = dagetattr;
2112         softc->disk->d_gone = dadiskgonecb;
2113         softc->disk->d_name = "da";
2114         softc->disk->d_drv1 = periph;
2115         if (cpi.maxio == 0)
2116                 softc->disk->d_maxsize = DFLTPHYS;      /* traditional default */
2117         else if (cpi.maxio > MAXPHYS)
2118                 softc->disk->d_maxsize = MAXPHYS;       /* for safety */
2119         else
2120                 softc->disk->d_maxsize = cpi.maxio;
2121         softc->disk->d_unit = periph->unit_number;
2122         softc->disk->d_flags = 0;
2123         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
2124                 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
2125         if ((cpi.hba_misc & PIM_UNMAPPED) != 0)
2126                 softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
2127         cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor,
2128             sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr));
2129         strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr));
2130         cam_strvis(&softc->disk->d_descr[strlen(softc->disk->d_descr)],
2131             cgd->inq_data.product, sizeof(cgd->inq_data.product),
2132             sizeof(softc->disk->d_descr) - strlen(softc->disk->d_descr));
2133         softc->disk->d_hba_vendor = cpi.hba_vendor;
2134         softc->disk->d_hba_device = cpi.hba_device;
2135         softc->disk->d_hba_subvendor = cpi.hba_subvendor;
2136         softc->disk->d_hba_subdevice = cpi.hba_subdevice;
2137
2138         /*
2139          * Acquire a reference to the periph before we register with GEOM.
2140          * We'll release this reference once GEOM calls us back (via
2141          * dadiskgonecb()) telling us that our provider has been freed.
2142          */
2143         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
2144                 xpt_print(periph->path, "%s: lost periph during "
2145                           "registration!\n", __func__);
2146                 cam_periph_lock(periph);
2147                 return (CAM_REQ_CMP_ERR);
2148         }
2149
2150         disk_create(softc->disk, DISK_VERSION);
2151         cam_periph_lock(periph);
2152
2153         /*
2154          * Add async callbacks for events of interest.
2155          * I don't bother checking if this fails as,
2156          * in most cases, the system will function just
2157          * fine without them and the only alternative
2158          * would be to not attach the device on failure.
2159          */
2160         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
2161             AC_ADVINFO_CHANGED | AC_SCSI_AEN | AC_UNIT_ATTENTION,
2162             daasync, periph, periph->path);
2163
2164         /*
2165          * Emit an attribute changed notification just in case 
2166          * physical path information arrived before our async
2167          * event handler was registered, but after anyone attaching
2168          * to our disk device polled it.
2169          */
2170         disk_attr_changed(softc->disk, "GEOM::physpath", M_NOWAIT);
2171
2172         /*
2173          * Schedule a periodic media polling events.
2174          */
2175         callout_init_mtx(&softc->mediapoll_c, periph->sim->mtx, 0);
2176         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) &&
2177             (cgd->inq_flags & SID_AEN) == 0 &&
2178             da_poll_period != 0)
2179                 callout_reset(&softc->mediapoll_c, da_poll_period * hz,
2180                     damediapoll, periph);
2181
2182         xpt_schedule(periph, CAM_PRIORITY_DEV);
2183
2184         return(CAM_REQ_CMP);
2185 }
2186
2187 static void
2188 dastart(struct cam_periph *periph, union ccb *start_ccb)
2189 {
2190         struct da_softc *softc;
2191
2192         softc = (struct da_softc *)periph->softc;
2193
2194         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n"));
2195
2196 skipstate:
2197         switch (softc->state) {
2198         case DA_STATE_NORMAL:
2199         {
2200                 struct bio *bp;
2201                 uint8_t tag_code;
2202
2203                 /* Execute immediate CCB if waiting. */
2204                 if (periph->immediate_priority <= periph->pinfo.priority) {
2205                         CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
2206                                         ("queuing for immediate ccb\n"));
2207                         start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
2208                         SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
2209                                           periph_links.sle);
2210                         periph->immediate_priority = CAM_PRIORITY_NONE;
2211                         wakeup(&periph->ccb_list);
2212                         /* May have more work to do, so ensure we stay scheduled */
2213                         daschedule(periph);
2214                         break;
2215                 }
2216
2217                 /* Run BIO_DELETE if not running yet. */
2218                 if (!softc->delete_running &&
2219                     (bp = bioq_first(&softc->delete_queue)) != NULL) {
2220                         if (softc->delete_func != NULL) {
2221                                 softc->delete_func(periph, start_ccb, bp);
2222                                 goto out;
2223                         } else {
2224                                 bioq_flush(&softc->delete_queue, NULL, 0);
2225                                 /* FALLTHROUGH */
2226                         }
2227                 }
2228
2229                 /* Run regular command. */
2230                 bp = bioq_takefirst(&softc->bio_queue);
2231                 if (bp == NULL) {
2232                         if (softc->tur) {
2233                                 softc->tur = 0;
2234                                 scsi_test_unit_ready(&start_ccb->csio,
2235                                      /*retries*/ da_retry_count,
2236                                      dadone,
2237                                      MSG_SIMPLE_Q_TAG,
2238                                      SSD_FULL_SIZE,
2239                                      da_default_timeout * 1000);
2240                                 start_ccb->ccb_h.ccb_bp = NULL;
2241                                 start_ccb->ccb_h.ccb_state = DA_CCB_TUR;
2242                                 xpt_action(start_ccb);
2243                         } else
2244                                 xpt_release_ccb(start_ccb);
2245                         break;
2246                 }
2247                 if (softc->tur) {
2248                         softc->tur = 0;
2249                         cam_periph_release_locked(periph);
2250                 }
2251
2252                 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
2253                     (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
2254                         softc->flags &= ~DA_FLAG_NEED_OTAG;
2255                         softc->ordered_tag_count++;
2256                         tag_code = MSG_ORDERED_Q_TAG;
2257                 } else {
2258                         tag_code = MSG_SIMPLE_Q_TAG;
2259                 }
2260
2261                 switch (bp->bio_cmd) {
2262                 case BIO_WRITE:
2263                         softc->flags |= DA_FLAG_DIRTY;
2264                         /* FALLTHROUGH */
2265                 case BIO_READ:
2266                         scsi_read_write(&start_ccb->csio,
2267                                         /*retries*/da_retry_count,
2268                                         /*cbfcnp*/dadone,
2269                                         /*tag_action*/tag_code,
2270                                         /*read_op*/(bp->bio_cmd == BIO_READ ?
2271                                         SCSI_RW_READ : SCSI_RW_WRITE) |
2272                                         ((bp->bio_flags & BIO_UNMAPPED) != 0 ?
2273                                         SCSI_RW_BIO : 0),
2274                                         /*byte2*/0,
2275                                         softc->minimum_cmd_size,
2276                                         /*lba*/bp->bio_pblkno,
2277                                         /*block_count*/bp->bio_bcount /
2278                                         softc->params.secsize,
2279                                         /*data_ptr*/ (bp->bio_flags &
2280                                         BIO_UNMAPPED) != 0 ? (void *)bp :
2281                                         bp->bio_data,
2282                                         /*dxfer_len*/ bp->bio_bcount,
2283                                         /*sense_len*/SSD_FULL_SIZE,
2284                                         da_default_timeout * 1000);
2285                         break;
2286                 case BIO_FLUSH:
2287                         /*
2288                          * BIO_FLUSH doesn't currently communicate
2289                          * range data, so we synchronize the cache
2290                          * over the whole disk.  We also force
2291                          * ordered tag semantics the flush applies
2292                          * to all previously queued I/O.
2293                          */
2294                         scsi_synchronize_cache(&start_ccb->csio,
2295                                                /*retries*/1,
2296                                                /*cbfcnp*/dadone,
2297                                                MSG_ORDERED_Q_TAG,
2298                                                /*begin_lba*/0,
2299                                                /*lb_count*/0,
2300                                                SSD_FULL_SIZE,
2301                                                da_default_timeout*1000);
2302                         break;
2303                 }
2304                 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
2305
2306 out:
2307                 /*
2308                  * Block out any asyncronous callbacks
2309                  * while we touch the pending ccb list.
2310                  */
2311                 LIST_INSERT_HEAD(&softc->pending_ccbs,
2312                                  &start_ccb->ccb_h, periph_links.le);
2313                 softc->outstanding_cmds++;
2314
2315                 /* We expect a unit attention from this device */
2316                 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
2317                         start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
2318                         softc->flags &= ~DA_FLAG_RETRY_UA;
2319                 }
2320
2321                 start_ccb->ccb_h.ccb_bp = bp;
2322                 xpt_action(start_ccb);
2323
2324                 /* May have more work to do, so ensure we stay scheduled */
2325                 daschedule(periph);
2326                 break;
2327         }
2328         case DA_STATE_PROBE_RC:
2329         {
2330                 struct scsi_read_capacity_data *rcap;
2331
2332                 rcap = (struct scsi_read_capacity_data *)
2333                     malloc(sizeof(*rcap), M_SCSIDA, M_NOWAIT|M_ZERO);
2334                 if (rcap == NULL) {
2335                         printf("dastart: Couldn't malloc read_capacity data\n");
2336                         /* da_free_periph??? */
2337                         break;
2338                 }
2339                 scsi_read_capacity(&start_ccb->csio,
2340                                    /*retries*/da_retry_count,
2341                                    dadone,
2342                                    MSG_SIMPLE_Q_TAG,
2343                                    rcap,
2344                                    SSD_FULL_SIZE,
2345                                    /*timeout*/5000);
2346                 start_ccb->ccb_h.ccb_bp = NULL;
2347                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC;
2348                 xpt_action(start_ccb);
2349                 break;
2350         }
2351         case DA_STATE_PROBE_RC16:
2352         {
2353                 struct scsi_read_capacity_data_long *rcaplong;
2354
2355                 rcaplong = (struct scsi_read_capacity_data_long *)
2356                         malloc(sizeof(*rcaplong), M_SCSIDA, M_NOWAIT|M_ZERO);
2357                 if (rcaplong == NULL) {
2358                         printf("dastart: Couldn't malloc read_capacity data\n");
2359                         /* da_free_periph??? */
2360                         break;
2361                 }
2362                 scsi_read_capacity_16(&start_ccb->csio,
2363                                       /*retries*/ da_retry_count,
2364                                       /*cbfcnp*/ dadone,
2365                                       /*tag_action*/ MSG_SIMPLE_Q_TAG,
2366                                       /*lba*/ 0,
2367                                       /*reladr*/ 0,
2368                                       /*pmi*/ 0,
2369                                       rcaplong,
2370                                       /*sense_len*/ SSD_FULL_SIZE,
2371                                       /*timeout*/ da_default_timeout * 1000);
2372                 start_ccb->ccb_h.ccb_bp = NULL;
2373                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_RC16;
2374                 xpt_action(start_ccb);
2375                 break;
2376         }
2377         case DA_STATE_PROBE_LBP:
2378         {
2379                 struct scsi_vpd_logical_block_prov *lbp;
2380
2381                 if (!scsi_vpd_supported_page(periph, SVPD_LBP)) {
2382                         /*
2383                          * If we get here we don't support any SBC-3 delete
2384                          * methods with UNMAP as the Logical Block Provisioning
2385                          * VPD page support is required for devices which
2386                          * support it according to T10/1799-D Revision 31
2387                          * however older revisions of the spec don't mandate
2388                          * this so we currently don't remove these methods
2389                          * from the available set.
2390                          */
2391                         softc->state = DA_STATE_PROBE_BLK_LIMITS;
2392                         goto skipstate;
2393                 }
2394
2395                 lbp = (struct scsi_vpd_logical_block_prov *)
2396                         malloc(sizeof(*lbp), M_SCSIDA, M_NOWAIT|M_ZERO);
2397
2398                 if (lbp == NULL) {
2399                         printf("dastart: Couldn't malloc lbp data\n");
2400                         /* da_free_periph??? */
2401                         break;
2402                 }
2403
2404                 scsi_inquiry(&start_ccb->csio,
2405                              /*retries*/da_retry_count,
2406                              /*cbfcnp*/dadone,
2407                              /*tag_action*/MSG_SIMPLE_Q_TAG,
2408                              /*inq_buf*/(u_int8_t *)lbp,
2409                              /*inq_len*/sizeof(*lbp),
2410                              /*evpd*/TRUE,
2411                              /*page_code*/SVPD_LBP,
2412                              /*sense_len*/SSD_MIN_SIZE,
2413                              /*timeout*/da_default_timeout * 1000);
2414                 start_ccb->ccb_h.ccb_bp = NULL;
2415                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_LBP;
2416                 xpt_action(start_ccb);
2417                 break;
2418         }
2419         case DA_STATE_PROBE_BLK_LIMITS:
2420         {
2421                 struct scsi_vpd_block_limits *block_limits;
2422
2423                 if (!scsi_vpd_supported_page(periph, SVPD_BLOCK_LIMITS)) {
2424                         /* Not supported skip to next probe */
2425                         softc->state = DA_STATE_PROBE_BDC;
2426                         goto skipstate;
2427                 }
2428
2429                 block_limits = (struct scsi_vpd_block_limits *)
2430                         malloc(sizeof(*block_limits), M_SCSIDA, M_NOWAIT|M_ZERO);
2431
2432                 if (block_limits == NULL) {
2433                         printf("dastart: Couldn't malloc block_limits data\n");
2434                         /* da_free_periph??? */
2435                         break;
2436                 }
2437
2438                 scsi_inquiry(&start_ccb->csio,
2439                              /*retries*/da_retry_count,
2440                              /*cbfcnp*/dadone,
2441                              /*tag_action*/MSG_SIMPLE_Q_TAG,
2442                              /*inq_buf*/(u_int8_t *)block_limits,
2443                              /*inq_len*/sizeof(*block_limits),
2444                              /*evpd*/TRUE,
2445                              /*page_code*/SVPD_BLOCK_LIMITS,
2446                              /*sense_len*/SSD_MIN_SIZE,
2447                              /*timeout*/da_default_timeout * 1000);
2448                 start_ccb->ccb_h.ccb_bp = NULL;
2449                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BLK_LIMITS;
2450                 xpt_action(start_ccb);
2451                 break;
2452         }
2453         case DA_STATE_PROBE_BDC:
2454         {
2455                 struct scsi_vpd_block_characteristics *bdc;
2456
2457                 if (!scsi_vpd_supported_page(periph, SVPD_BDC)) {
2458                         softc->state = DA_STATE_PROBE_ATA;
2459                         goto skipstate;
2460                 }
2461
2462                 bdc = (struct scsi_vpd_block_characteristics *)
2463                         malloc(sizeof(*bdc), M_SCSIDA, M_NOWAIT|M_ZERO);
2464
2465                 if (bdc == NULL) {
2466                         printf("dastart: Couldn't malloc bdc data\n");
2467                         /* da_free_periph??? */
2468                         break;
2469                 }
2470
2471                 scsi_inquiry(&start_ccb->csio,
2472                              /*retries*/da_retry_count,
2473                              /*cbfcnp*/dadone,
2474                              /*tag_action*/MSG_SIMPLE_Q_TAG,
2475                              /*inq_buf*/(u_int8_t *)bdc,
2476                              /*inq_len*/sizeof(*bdc),
2477                              /*evpd*/TRUE,
2478                              /*page_code*/SVPD_BDC,
2479                              /*sense_len*/SSD_MIN_SIZE,
2480                              /*timeout*/da_default_timeout * 1000);
2481                 start_ccb->ccb_h.ccb_bp = NULL;
2482                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_BDC;
2483                 xpt_action(start_ccb);
2484                 break;
2485         }
2486         case DA_STATE_PROBE_ATA:
2487         {
2488                 struct ata_params *ata_params;
2489
2490                 if (!scsi_vpd_supported_page(periph, SVPD_ATA_INFORMATION)) {
2491                         daprobedone(periph, start_ccb);
2492                         break;
2493                 }
2494
2495                 ata_params = (struct ata_params*)
2496                         malloc(sizeof(*ata_params), M_SCSIDA, M_NOWAIT|M_ZERO);
2497
2498                 if (ata_params == NULL) {
2499                         printf("dastart: Couldn't malloc ata_params data\n");
2500                         /* da_free_periph??? */
2501                         break;
2502                 }
2503
2504                 scsi_ata_identify(&start_ccb->csio,
2505                                   /*retries*/da_retry_count,
2506                                   /*cbfcnp*/dadone,
2507                                   /*tag_action*/MSG_SIMPLE_Q_TAG,
2508                                   /*data_ptr*/(u_int8_t *)ata_params,
2509                                   /*dxfer_len*/sizeof(*ata_params),
2510                                   /*sense_len*/SSD_FULL_SIZE,
2511                                   /*timeout*/da_default_timeout * 1000);
2512                 start_ccb->ccb_h.ccb_bp = NULL;
2513                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE_ATA;
2514                 xpt_action(start_ccb);
2515                 break;
2516         }
2517         }
2518 }
2519
2520 /*
2521  * In each of the methods below, while its the caller's
2522  * responsibility to ensure the request will fit into a
2523  * single device request, we might have changed the delete
2524  * method due to the device incorrectly advertising either
2525  * its supported methods or limits.
2526  * 
2527  * To prevent this causing further issues we validate the
2528  * against the methods limits, and warn which would
2529  * otherwise be unnecessary.
2530  */
2531 static void
2532 da_delete_unmap(struct cam_periph *periph, union ccb *ccb, struct bio *bp)
2533 {
2534         struct da_softc *softc = (struct da_softc *)periph->softc;;
2535         struct bio *bp1;
2536         uint8_t *buf = softc->unmap_buf;
2537         uint64_t lba, lastlba = (uint64_t)-1;
2538         uint64_t totalcount = 0;
2539         uint64_t count;
2540         uint32_t lastcount = 0, c;
2541         uint32_t off, ranges = 0;
2542
2543         /*
2544          * Currently this doesn't take the UNMAP
2545          * Granularity and Granularity Alignment
2546          * fields into account.
2547          *
2548          * This could result in both unoptimal unmap
2549          * requests as as well as UNMAP calls unmapping
2550          * fewer LBA's than requested.
2551          */
2552
2553         softc->delete_running = 1;
2554         bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
2555         bp1 = bp;
2556         do {
2557                 bioq_remove(&softc->delete_queue, bp1);
2558                 if (bp1 != bp)
2559                         bioq_insert_tail(&softc->delete_run_queue, bp1);
2560                 lba = bp1->bio_pblkno;
2561                 count = bp1->bio_bcount / softc->params.secsize;
2562
2563                 /* Try to extend the previous range. */
2564                 if (lba == lastlba) {
2565                         c = min(count, softc->unmap_max_lba - lastcount);
2566                         lastcount += c;
2567                         off = ((ranges - 1) * UNMAP_RANGE_SIZE) +
2568                               UNMAP_HEAD_SIZE;
2569                         scsi_ulto4b(lastcount, &buf[off + 8]);
2570                         count -= c;
2571                         lba +=c;
2572                         totalcount += c;
2573                 }
2574
2575                 while (count > 0) {
2576                         c = min(count, softc->unmap_max_lba);
2577                         if (totalcount + c > softc->unmap_max_lba ||
2578                             ranges >= softc->unmap_max_ranges) {
2579                                 xpt_print(periph->path,
2580                                     "%s issuing short delete %ld > %ld"
2581                                     "|| %d >= %d",
2582                                     da_delete_method_desc[softc->delete_method],
2583                                     totalcount + c, softc->unmap_max_lba,
2584                                     ranges, softc->unmap_max_ranges);
2585                                 break;
2586                         }
2587                         off = (ranges * UNMAP_RANGE_SIZE) + UNMAP_HEAD_SIZE;
2588                         scsi_u64to8b(lba, &buf[off + 0]);
2589                         scsi_ulto4b(c, &buf[off + 8]);
2590                         lba += c;
2591                         totalcount += c;
2592                         ranges++;
2593                         count -= c;
2594                         lastcount = c;
2595                 }
2596                 lastlba = lba;
2597                 bp1 = bioq_first(&softc->delete_queue);
2598                 if (bp1 == NULL || ranges >= softc->unmap_max_ranges ||
2599                     totalcount + bp1->bio_bcount /
2600                     softc->params.secsize > softc->unmap_max_lba)
2601                         break;
2602         } while (1);
2603         scsi_ulto2b(ranges * 16 + 6, &buf[0]);
2604         scsi_ulto2b(ranges * 16, &buf[2]);
2605
2606         scsi_unmap(&ccb->csio,
2607                    /*retries*/da_retry_count,
2608                    /*cbfcnp*/dadone,
2609                    /*tag_action*/MSG_SIMPLE_Q_TAG,
2610                    /*byte2*/0,
2611                    /*data_ptr*/ buf,
2612                    /*dxfer_len*/ ranges * 16 + 8,
2613                    /*sense_len*/SSD_FULL_SIZE,
2614                    da_default_timeout * 1000);
2615         ccb->ccb_h.ccb_state = DA_CCB_DELETE;
2616 }
2617
2618 static void
2619 da_delete_trim(struct cam_periph *periph, union ccb *ccb, struct bio *bp)
2620 {
2621         struct da_softc *softc = (struct da_softc *)periph->softc;
2622         struct bio *bp1;
2623         uint8_t *buf = softc->unmap_buf;
2624         uint64_t lastlba = (uint64_t)-1;
2625         uint64_t count;
2626         uint64_t lba;
2627         uint32_t lastcount = 0, c, requestcount;
2628         int ranges = 0, off, block_count;
2629
2630         softc->delete_running = 1;
2631         bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
2632         bp1 = bp;
2633         do {
2634                 bioq_remove(&softc->delete_queue, bp1);
2635                 if (bp1 != bp)
2636                         bioq_insert_tail(&softc->delete_run_queue, bp1);
2637                 lba = bp1->bio_pblkno;
2638                 count = bp1->bio_bcount / softc->params.secsize;
2639                 requestcount = count;
2640
2641                 /* Try to extend the previous range. */
2642                 if (lba == lastlba) {
2643                         c = min(count, ATA_DSM_RANGE_MAX - lastcount);
2644                         lastcount += c;
2645                         off = (ranges - 1) * 8;
2646                         buf[off + 6] = lastcount & 0xff;
2647                         buf[off + 7] = (lastcount >> 8) & 0xff;
2648                         count -= c;
2649                         lba += c;
2650                 }
2651
2652                 while (count > 0) {
2653                         c = min(count, ATA_DSM_RANGE_MAX);
2654                         off = ranges * 8;
2655
2656                         buf[off + 0] = lba & 0xff;
2657                         buf[off + 1] = (lba >> 8) & 0xff;
2658                         buf[off + 2] = (lba >> 16) & 0xff;
2659                         buf[off + 3] = (lba >> 24) & 0xff;
2660                         buf[off + 4] = (lba >> 32) & 0xff;
2661                         buf[off + 5] = (lba >> 40) & 0xff;
2662                         buf[off + 6] = c & 0xff;
2663                         buf[off + 7] = (c >> 8) & 0xff;
2664                         lba += c;
2665                         ranges++;
2666                         count -= c;
2667                         lastcount = c;
2668                         if (count != 0 && ranges == softc->trim_max_ranges) {
2669                                 xpt_print(periph->path,
2670                                     "%s issuing short delete %ld > %ld",
2671                                     da_delete_method_desc[softc->delete_method],
2672                                     requestcount,
2673                                     (softc->trim_max_ranges - ranges) *
2674                                     ATA_DSM_RANGE_MAX);
2675                                 break;
2676                         }
2677                 }
2678                 lastlba = lba;
2679                 bp1 = bioq_first(&softc->delete_queue);
2680                 if (bp1 == NULL || bp1->bio_bcount / softc->params.secsize >
2681                     (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX)
2682                         break;
2683         } while (1);
2684
2685         block_count = (ranges + ATA_DSM_BLK_RANGES - 1) / ATA_DSM_BLK_RANGES;
2686         scsi_ata_trim(&ccb->csio,
2687                       /*retries*/da_retry_count,
2688                       /*cbfcnp*/dadone,
2689                       /*tag_action*/MSG_SIMPLE_Q_TAG,
2690                       block_count,
2691                       /*data_ptr*/buf,
2692                       /*dxfer_len*/block_count * ATA_DSM_BLK_SIZE,
2693                       /*sense_len*/SSD_FULL_SIZE,
2694                       da_default_timeout * 1000);
2695         ccb->ccb_h.ccb_state = DA_CCB_DELETE;
2696 }
2697
2698 /*
2699  * We calculate ws_max_blks here based off d_delmaxsize instead
2700  * of using softc->ws_max_blks as it is absolute max for the
2701  * device not the protocol max which may well be lower
2702  */
2703 static void
2704 da_delete_ws(struct cam_periph *periph, union ccb *ccb, struct bio *bp)
2705 {
2706         struct da_softc *softc;
2707         struct bio *bp1;
2708         uint64_t ws_max_blks;
2709         uint64_t lba;
2710         uint64_t count; /* forward compat with WS32 */
2711
2712         softc = (struct da_softc *)periph->softc;
2713         ws_max_blks = softc->disk->d_delmaxsize / softc->params.secsize;
2714         softc->delete_running = 1;
2715         lba = bp->bio_pblkno;
2716         count = 0;
2717         bp1 = bp;
2718         do {
2719                 bioq_remove(&softc->delete_queue, bp1);
2720                 if (bp1 != bp)
2721                         bioq_insert_tail(&softc->delete_run_queue, bp1);
2722                 count += bp1->bio_bcount / softc->params.secsize;
2723                 if (count > ws_max_blks) {
2724                         count = min(count, ws_max_blks);
2725                         xpt_print(periph->path,
2726                             "%s issuing short delete %ld > %ld",
2727                             da_delete_method_desc[softc->delete_method],
2728                             count, ws_max_blks);
2729                         break;
2730                 }
2731                 bp1 = bioq_first(&softc->delete_queue);
2732                 if (bp1 == NULL || lba + count != bp1->bio_pblkno ||
2733                     count + bp1->bio_bcount /
2734                     softc->params.secsize > ws_max_blks)
2735                         break;
2736         } while (1);
2737
2738         scsi_write_same(&ccb->csio,
2739                         /*retries*/da_retry_count,
2740                         /*cbfcnp*/dadone,
2741                         /*tag_action*/MSG_SIMPLE_Q_TAG,
2742                         /*byte2*/softc->delete_method ==
2743                             DA_DELETE_ZERO ? 0 : SWS_UNMAP,
2744                         softc->delete_method == DA_DELETE_WS16 ? 16 : 10,
2745                         /*lba*/lba,
2746                         /*block_count*/count,
2747                         /*data_ptr*/ __DECONST(void *, zero_region),
2748                         /*dxfer_len*/ softc->params.secsize,
2749                         /*sense_len*/SSD_FULL_SIZE,
2750                         da_default_timeout * 1000);
2751         ccb->ccb_h.ccb_state = DA_CCB_DELETE;
2752 }
2753
2754 static int
2755 cmd6workaround(union ccb *ccb)
2756 {
2757         struct scsi_rw_6 cmd6;
2758         struct scsi_rw_10 *cmd10;
2759         struct da_softc *softc;
2760         u_int8_t *cdb;
2761         struct bio *bp;
2762         int frozen;
2763
2764         cdb = ccb->csio.cdb_io.cdb_bytes;
2765         softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
2766
2767         if (ccb->ccb_h.ccb_state == DA_CCB_DELETE) {
2768                 da_delete_methods old_method = softc->delete_method;
2769
2770                 /*
2771                  * Typically there are two reasons for failure here
2772                  * 1. Delete method was detected as supported but isn't
2773                  * 2. Delete failed due to invalid params e.g. too big
2774                  *
2775                  * While we will attempt to choose an alternative delete method
2776                  * this may result in short deletes if the existing delete
2777                  * requests from geom are big for the new method choosen.
2778                  *
2779                  * This method assumes that the error which triggered this
2780                  * will not retry the io otherwise a panic will occur
2781                  */
2782                 dadeleteflag(softc, old_method, 0);
2783                 dadeletemethodchoose(softc, DA_DELETE_DISABLE);
2784                 if (softc->delete_method == DA_DELETE_DISABLE)
2785                         xpt_print(ccb->ccb_h.path,
2786                                   "%s failed, disabling BIO_DELETE\n",
2787                                   da_delete_method_desc[old_method]);
2788                 else
2789                         xpt_print(ccb->ccb_h.path,
2790                                   "%s failed, switching to %s BIO_DELETE\n",
2791                                   da_delete_method_desc[old_method],
2792                                   da_delete_method_desc[softc->delete_method]);
2793
2794                 if (DA_SIO) {
2795                         while ((bp = bioq_takefirst(&softc->delete_run_queue))
2796                             != NULL)
2797                                 bioq_disksort(&softc->delete_queue, bp);
2798                 } else {
2799                         while ((bp = bioq_takefirst(&softc->delete_run_queue))
2800                             != NULL)
2801                                 bioq_insert_tail(&softc->delete_queue, bp);
2802                 }
2803                 bioq_insert_tail(&softc->delete_queue,
2804                     (struct bio *)ccb->ccb_h.ccb_bp);
2805                 ccb->ccb_h.ccb_bp = NULL;
2806                 return (0);
2807         }
2808
2809         /* Detect unsupported PREVENT ALLOW MEDIUM REMOVAL. */
2810         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) == 0 &&
2811             (*cdb == PREVENT_ALLOW) &&
2812             (softc->quirks & DA_Q_NO_PREVENT) == 0) {
2813                 if (bootverbose)
2814                         xpt_print(ccb->ccb_h.path,
2815                             "PREVENT ALLOW MEDIUM REMOVAL not supported.\n");
2816                 softc->quirks |= DA_Q_NO_PREVENT;
2817                 return (0);
2818         }
2819
2820         /* Detect unsupported SYNCHRONIZE CACHE(10). */
2821         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) == 0 &&
2822             (*cdb == SYNCHRONIZE_CACHE) &&
2823             (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
2824                 if (bootverbose)
2825                         xpt_print(ccb->ccb_h.path,
2826                             "SYNCHRONIZE CACHE(10) not supported.\n");
2827                 softc->quirks |= DA_Q_NO_SYNC_CACHE;
2828                 softc->disk->d_flags &= ~DISKFLAG_CANFLUSHCACHE;
2829                 return (0);
2830         }
2831
2832         /* Translation only possible if CDB is an array and cmd is R/W6 */
2833         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
2834             (*cdb != READ_6 && *cdb != WRITE_6))
2835                 return 0;
2836
2837         xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
2838             "increasing minimum_cmd_size to 10.\n");
2839         softc->minimum_cmd_size = 10;
2840
2841         bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
2842         cmd10 = (struct scsi_rw_10 *)cdb;
2843         cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
2844         cmd10->byte2 = 0;
2845         scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
2846         cmd10->reserved = 0;
2847         scsi_ulto2b(cmd6.length, cmd10->length);
2848         cmd10->control = cmd6.control;
2849         ccb->csio.cdb_len = sizeof(*cmd10);
2850
2851         /* Requeue request, unfreezing queue if necessary */
2852         frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
2853         ccb->ccb_h.status = CAM_REQUEUE_REQ;
2854         xpt_action(ccb);
2855         if (frozen) {
2856                 cam_release_devq(ccb->ccb_h.path,
2857                                  /*relsim_flags*/0,
2858                                  /*reduction*/0,
2859                                  /*timeout*/0,
2860                                  /*getcount_only*/0);
2861         }
2862         return (ERESTART);
2863 }
2864
2865 static void
2866 dadone(struct cam_periph *periph, union ccb *done_ccb)
2867 {
2868         struct da_softc *softc;
2869         struct ccb_scsiio *csio;
2870         u_int32_t  priority;
2871         da_ccb_state state;
2872
2873         softc = (struct da_softc *)periph->softc;
2874         priority = done_ccb->ccb_h.pinfo.priority;
2875
2876         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
2877
2878         csio = &done_ccb->csio;
2879         state = csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK;
2880         switch (state) {
2881         case DA_CCB_BUFFER_IO:
2882         case DA_CCB_DELETE:
2883         {
2884                 struct bio *bp, *bp1;
2885
2886                 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2887                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2888                         int error;
2889                         int sf;
2890
2891                         if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
2892                                 sf = SF_RETRY_UA;
2893                         else
2894                                 sf = 0;
2895
2896                         error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
2897                         if (error == ERESTART) {
2898                                 /*
2899                                  * A retry was scheduled, so
2900                                  * just return.
2901                                  */
2902                                 return;
2903                         }
2904                         bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2905                         if (error != 0) {
2906                                 int queued_error;
2907
2908                                 /*
2909                                  * return all queued I/O with EIO, so that
2910                                  * the client can retry these I/Os in the
2911                                  * proper order should it attempt to recover.
2912                                  */
2913                                 queued_error = EIO;
2914
2915                                 if (error == ENXIO
2916                                  && (softc->flags & DA_FLAG_PACK_INVALID)== 0) {
2917                                         /*
2918                                          * Catastrophic error.  Mark our pack as
2919                                          * invalid.
2920                                          */
2921                                         /*
2922                                          * XXX See if this is really a media
2923                                          * XXX change first?
2924                                          */
2925                                         xpt_print(periph->path,
2926                                             "Invalidating pack\n");
2927                                         softc->flags |= DA_FLAG_PACK_INVALID;
2928                                         queued_error = ENXIO;
2929                                 }
2930                                 bioq_flush(&softc->bio_queue, NULL,
2931                                            queued_error);
2932                                 if (bp != NULL) {
2933                                         bp->bio_error = error;
2934                                         bp->bio_resid = bp->bio_bcount;
2935                                         bp->bio_flags |= BIO_ERROR;
2936                                 }
2937                         } else if (bp != NULL) {
2938                                 bp->bio_resid = csio->resid;
2939                                 bp->bio_error = 0;
2940                                 if (bp->bio_resid != 0)
2941                                         bp->bio_flags |= BIO_ERROR;
2942                         }
2943                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2944                                 cam_release_devq(done_ccb->ccb_h.path,
2945                                                  /*relsim_flags*/0,
2946                                                  /*reduction*/0,
2947                                                  /*timeout*/0,
2948                                                  /*getcount_only*/0);
2949                 } else if (bp != NULL) {
2950                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2951                                 panic("REQ_CMP with QFRZN");
2952                         bp->bio_resid = csio->resid;
2953                         if (csio->resid > 0)
2954                                 bp->bio_flags |= BIO_ERROR;
2955                         if (softc->error_inject != 0) {
2956                                 bp->bio_error = softc->error_inject;
2957                                 bp->bio_resid = bp->bio_bcount;
2958                                 bp->bio_flags |= BIO_ERROR;
2959                                 softc->error_inject = 0;
2960                         }
2961
2962                 }
2963
2964                 /*
2965                  * Block out any asyncronous callbacks
2966                  * while we touch the pending ccb list.
2967                  */
2968                 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
2969                 softc->outstanding_cmds--;
2970                 if (softc->outstanding_cmds == 0)
2971                         softc->flags |= DA_FLAG_WENT_IDLE;
2972
2973                 if (state == DA_CCB_DELETE) {
2974                         while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
2975                             != NULL) {
2976                                 bp1->bio_resid = bp->bio_resid;
2977                                 bp1->bio_error = bp->bio_error;
2978                                 if (bp->bio_flags & BIO_ERROR)
2979                                         bp1->bio_flags |= BIO_ERROR;
2980                                 biodone(bp1);
2981                         }
2982                         softc->delete_running = 0;
2983                         if (bp != NULL)
2984                                 biodone(bp);
2985                         daschedule(periph);
2986                 } else if (bp != NULL)
2987                         biodone(bp);
2988                 break;
2989         }
2990         case DA_CCB_PROBE_RC:
2991         case DA_CCB_PROBE_RC16:
2992         {
2993                 struct     scsi_read_capacity_data *rdcap;
2994                 struct     scsi_read_capacity_data_long *rcaplong;
2995                 char       announce_buf[80];
2996                 int        lbp;
2997
2998                 lbp = 0;
2999                 rdcap = NULL;
3000                 rcaplong = NULL;
3001                 if (state == DA_CCB_PROBE_RC)
3002                         rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
3003                 else
3004                         rcaplong = (struct scsi_read_capacity_data_long *)
3005                                 csio->data_ptr;
3006
3007                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3008                         struct disk_params *dp;
3009                         uint32_t block_size;
3010                         uint64_t maxsector;
3011                         u_int lbppbe;   /* LB per physical block exponent. */
3012                         u_int lalba;    /* Lowest aligned LBA. */
3013
3014                         if (state == DA_CCB_PROBE_RC) {
3015                                 block_size = scsi_4btoul(rdcap->length);
3016                                 maxsector = scsi_4btoul(rdcap->addr);
3017                                 lbppbe = 0;
3018                                 lalba = 0;
3019
3020                                 /*
3021                                  * According to SBC-2, if the standard 10
3022                                  * byte READ CAPACITY command returns 2^32,
3023                                  * we should issue the 16 byte version of
3024                                  * the command, since the device in question
3025                                  * has more sectors than can be represented
3026                                  * with the short version of the command.
3027                                  */
3028                                 if (maxsector == 0xffffffff) {
3029                                         free(rdcap, M_SCSIDA);
3030                                         xpt_release_ccb(done_ccb);
3031                                         softc->state = DA_STATE_PROBE_RC16;
3032                                         xpt_schedule(periph, priority);
3033                                         return;
3034                                 }
3035                         } else {
3036                                 block_size = scsi_4btoul(rcaplong->length);
3037                                 maxsector = scsi_8btou64(rcaplong->addr);
3038                                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
3039                                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
3040                         }
3041
3042                         /*
3043                          * Because GEOM code just will panic us if we
3044                          * give them an 'illegal' value we'll avoid that
3045                          * here.
3046                          */
3047                         if (block_size == 0 && maxsector == 0) {
3048                                 snprintf(announce_buf, sizeof(announce_buf),
3049                                         "0MB (no media?)");
3050                         } else if (block_size >= MAXPHYS || block_size == 0) {
3051                                 xpt_print(periph->path,
3052                                     "unsupportable block size %ju\n",
3053                                     (uintmax_t) block_size);
3054                                 announce_buf[0] = '\0';
3055                                 cam_periph_invalidate(periph);
3056                         } else {
3057                                 /*
3058                                  * We pass rcaplong into dasetgeom(),
3059                                  * because it will only use it if it is
3060                                  * non-NULL.
3061                                  */
3062                                 dasetgeom(periph, block_size, maxsector,
3063                                           rcaplong, sizeof(*rcaplong));
3064                                 lbp = (lalba & SRC16_LBPME_A);
3065                                 dp = &softc->params;
3066                                 snprintf(announce_buf, sizeof(announce_buf),
3067                                         "%juMB (%ju %u byte sectors: %dH %dS/T "
3068                                         "%dC)", (uintmax_t)
3069                                         (((uintmax_t)dp->secsize *
3070                                         dp->sectors) / (1024*1024)),
3071                                         (uintmax_t)dp->sectors,
3072                                         dp->secsize, dp->heads,
3073                                         dp->secs_per_track, dp->cylinders);
3074                         }
3075                 } else {
3076                         int     error;
3077
3078                         announce_buf[0] = '\0';
3079
3080                         /*
3081                          * Retry any UNIT ATTENTION type errors.  They
3082                          * are expected at boot.
3083                          */
3084                         error = daerror(done_ccb, CAM_RETRY_SELTO,
3085                                         SF_RETRY_UA|SF_NO_PRINT);
3086                         if (error == ERESTART) {
3087                                 /*
3088                                  * A retry was scheuled, so
3089                                  * just return.
3090                                  */
3091                                 return;
3092                         } else if (error != 0) {
3093                                 int asc, ascq;
3094                                 int sense_key, error_code;
3095                                 int have_sense;
3096                                 cam_status status;
3097                                 struct ccb_getdev cgd;
3098
3099                                 /* Don't wedge this device's queue */
3100                                 status = done_ccb->ccb_h.status;
3101                                 if ((status & CAM_DEV_QFRZN) != 0)
3102                                         cam_release_devq(done_ccb->ccb_h.path,
3103                                                          /*relsim_flags*/0,
3104                                                          /*reduction*/0,
3105                                                          /*timeout*/0,
3106                                                          /*getcount_only*/0);
3107
3108
3109                                 xpt_setup_ccb(&cgd.ccb_h, 
3110                                               done_ccb->ccb_h.path,
3111                                               CAM_PRIORITY_NORMAL);
3112                                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
3113                                 xpt_action((union ccb *)&cgd);
3114
3115                                 if (scsi_extract_sense_ccb(done_ccb,
3116                                     &error_code, &sense_key, &asc, &ascq))
3117                                         have_sense = TRUE;
3118                                 else
3119                                         have_sense = FALSE;
3120
3121                                 /*
3122                                  * If we tried READ CAPACITY(16) and failed,
3123                                  * fallback to READ CAPACITY(10).
3124                                  */
3125                                 if ((state == DA_CCB_PROBE_RC16) &&
3126                                     (softc->flags & DA_FLAG_CAN_RC16) &&
3127                                     (((csio->ccb_h.status & CAM_STATUS_MASK) ==
3128                                         CAM_REQ_INVALID) ||
3129                                      ((have_sense) &&
3130                                       (error_code == SSD_CURRENT_ERROR) &&
3131                                       (sense_key == SSD_KEY_ILLEGAL_REQUEST)))) {
3132                                         softc->flags &= ~DA_FLAG_CAN_RC16;
3133                                         free(rdcap, M_SCSIDA);
3134                                         xpt_release_ccb(done_ccb);
3135                                         softc->state = DA_STATE_PROBE_RC;
3136                                         xpt_schedule(periph, priority);
3137                                         return;
3138                                 } else
3139                                 /*
3140                                  * Attach to anything that claims to be a
3141                                  * direct access or optical disk device,
3142                                  * as long as it doesn't return a "Logical
3143                                  * unit not supported" (0x25) error.
3144                                  */
3145                                 if ((have_sense) && (asc != 0x25)
3146                                  && (error_code == SSD_CURRENT_ERROR)) {
3147                                         const char *sense_key_desc;
3148                                         const char *asc_desc;
3149
3150                                         scsi_sense_desc(sense_key, asc, ascq,
3151                                                         &cgd.inq_data,
3152                                                         &sense_key_desc,
3153                                                         &asc_desc);
3154                                         snprintf(announce_buf,
3155                                             sizeof(announce_buf),
3156                                                 "Attempt to query device "
3157                                                 "size failed: %s, %s",
3158                                                 sense_key_desc,
3159                                                 asc_desc);
3160                                 } else { 
3161                                         if (have_sense)
3162                                                 scsi_sense_print(
3163                                                         &done_ccb->csio);
3164                                         else {
3165                                                 xpt_print(periph->path,
3166                                                     "got CAM status %#x\n",
3167                                                     done_ccb->ccb_h.status);
3168                                         }
3169
3170                                         xpt_print(periph->path, "fatal error, "
3171                                             "failed to attach to device\n");
3172
3173                                         /*
3174                                          * Free up resources.
3175                                          */
3176                                         cam_periph_invalidate(periph);
3177                                 } 
3178                         }
3179                 }
3180                 free(csio->data_ptr, M_SCSIDA);
3181                 if (announce_buf[0] != '\0' && ((softc->flags & DA_FLAG_PROBED) == 0)) {
3182                         /*
3183                          * Create our sysctl variables, now that we know
3184                          * we have successfully attached.
3185                          */
3186                         /* increase the refcount */
3187                         if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
3188                                 taskqueue_enqueue(taskqueue_thread,
3189                                                   &softc->sysctl_task);
3190                                 xpt_announce_periph(periph, announce_buf);
3191                                 xpt_announce_quirks(periph, softc->quirks,
3192                                     DA_Q_BIT_STRING);
3193                         } else {
3194                                 xpt_print(periph->path, "fatal error, "
3195                                     "could not acquire reference count\n");
3196                         }
3197                 }
3198
3199                 /* Ensure re-probe doesn't see old delete. */
3200                 softc->delete_available = 0;
3201                 if (lbp) {
3202                         /*
3203                          * Based on older SBC-3 spec revisions
3204                          * any of the UNMAP methods "may" be
3205                          * available via LBP given this flag so
3206                          * we flag all of them as availble and
3207                          * then remove those which further
3208                          * probes confirm aren't available
3209                          * later.
3210                          *
3211                          * We could also check readcap(16) p_type
3212                          * flag to exclude one or more invalid
3213                          * write same (X) types here
3214                          */
3215                         dadeleteflag(softc, DA_DELETE_WS16, 1);
3216                         dadeleteflag(softc, DA_DELETE_WS10, 1);
3217                         dadeleteflag(softc, DA_DELETE_ZERO, 1);
3218                         dadeleteflag(softc, DA_DELETE_UNMAP, 1);
3219
3220                         xpt_release_ccb(done_ccb);
3221                         softc->state = DA_STATE_PROBE_LBP;
3222                         xpt_schedule(periph, priority);
3223                         return;
3224                 }
3225
3226                 xpt_release_ccb(done_ccb);
3227                 softc->state = DA_STATE_PROBE_BDC;
3228                 xpt_schedule(periph, priority);
3229                 return;
3230         }
3231         case DA_CCB_PROBE_LBP:
3232         {
3233                 struct scsi_vpd_logical_block_prov *lbp;
3234
3235                 lbp = (struct scsi_vpd_logical_block_prov *)csio->data_ptr;
3236
3237                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3238                         /*
3239                          * T10/1799-D Revision 31 states at least one of these
3240                          * must be supported but we don't currently enforce this.
3241                          */
3242                         dadeleteflag(softc, DA_DELETE_WS16,
3243                                      (lbp->flags & SVPD_LBP_WS16));
3244                         dadeleteflag(softc, DA_DELETE_WS10,
3245                                      (lbp->flags & SVPD_LBP_WS10));
3246                         dadeleteflag(softc, DA_DELETE_ZERO,
3247                                      (lbp->flags & SVPD_LBP_WS10));
3248                         dadeleteflag(softc, DA_DELETE_UNMAP,
3249                                      (lbp->flags & SVPD_LBP_UNMAP));
3250
3251                         if (lbp->flags & SVPD_LBP_UNMAP) {
3252                                 free(lbp, M_SCSIDA);
3253                                 xpt_release_ccb(done_ccb);
3254                                 softc->state = DA_STATE_PROBE_BLK_LIMITS;
3255                                 xpt_schedule(periph, priority);
3256                                 return;
3257                         }
3258                 } else {
3259                         int error;
3260                         error = daerror(done_ccb, CAM_RETRY_SELTO,
3261                                         SF_RETRY_UA|SF_NO_PRINT);
3262                         if (error == ERESTART)
3263                                 return;
3264                         else if (error != 0) {
3265                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3266                                         /* Don't wedge this device's queue */
3267                                         cam_release_devq(done_ccb->ccb_h.path,
3268                                                          /*relsim_flags*/0,
3269                                                          /*reduction*/0,
3270                                                          /*timeout*/0,
3271                                                          /*getcount_only*/0);
3272                                 }
3273
3274                                 /*
3275                                  * Failure indicates we don't support any SBC-3
3276                                  * delete methods with UNMAP
3277                                  */
3278                         }
3279                 }
3280
3281                 free(lbp, M_SCSIDA);
3282                 xpt_release_ccb(done_ccb);
3283                 softc->state = DA_STATE_PROBE_BDC;
3284                 xpt_schedule(periph, priority);
3285                 return;
3286         }
3287         case DA_CCB_PROBE_BLK_LIMITS:
3288         {
3289                 struct scsi_vpd_block_limits *block_limits;
3290
3291                 block_limits = (struct scsi_vpd_block_limits *)csio->data_ptr;
3292
3293                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3294                         uint32_t max_unmap_lba_cnt = scsi_4btoul(
3295                                 block_limits->max_unmap_lba_cnt);
3296                         uint32_t max_unmap_blk_cnt = scsi_4btoul(
3297                                 block_limits->max_unmap_blk_cnt);
3298                         uint64_t ws_max_blks = scsi_8btou64(
3299                                 block_limits->max_write_same_length);
3300                         /*
3301                          * We should already support UNMAP but we check lba
3302                          * and block count to be sure
3303                          */
3304                         if (max_unmap_lba_cnt != 0x00L &&
3305                             max_unmap_blk_cnt != 0x00L) {
3306                                 softc->unmap_max_lba = max_unmap_lba_cnt;
3307                                 softc->unmap_max_ranges = min(max_unmap_blk_cnt,
3308                                         UNMAP_MAX_RANGES);
3309                         } else {
3310                                 /*
3311                                  * Unexpected UNMAP limits which means the
3312                                  * device doesn't actually support UNMAP
3313                                  */
3314                                 dadeleteflag(softc, DA_DELETE_UNMAP, 0);
3315                         }
3316
3317                         if (ws_max_blks != 0x00L)
3318                                 softc->ws_max_blks = ws_max_blks;
3319                 } else {
3320                         int error;
3321                         error = daerror(done_ccb, CAM_RETRY_SELTO,
3322                                         SF_RETRY_UA|SF_NO_PRINT);
3323                         if (error == ERESTART)
3324                                 return;
3325                         else if (error != 0) {
3326                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3327                                         /* Don't wedge this device's queue */
3328                                         cam_release_devq(done_ccb->ccb_h.path,
3329                                                          /*relsim_flags*/0,
3330                                                          /*reduction*/0,
3331                                                          /*timeout*/0,
3332                                                          /*getcount_only*/0);
3333                                 }
3334
3335                                 /*
3336                                  * Failure here doesn't mean UNMAP is not
3337                                  * supported as this is an optional page.
3338                                  */
3339                                 softc->unmap_max_lba = 1;
3340                                 softc->unmap_max_ranges = 1;
3341                         }
3342                 }
3343
3344                 free(block_limits, M_SCSIDA);
3345                 xpt_release_ccb(done_ccb);
3346                 softc->state = DA_STATE_PROBE_BDC;
3347                 xpt_schedule(periph, priority);
3348                 return;
3349         }
3350         case DA_CCB_PROBE_BDC:
3351         {
3352                 struct scsi_vpd_block_characteristics *bdc;
3353
3354                 bdc = (struct scsi_vpd_block_characteristics *)csio->data_ptr;
3355
3356                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3357                         /*
3358                          * Disable queue sorting for non-rotational media
3359                          * by default.
3360                          */
3361                         if (scsi_2btoul(bdc->medium_rotation_rate) ==
3362                             SVPD_BDC_RATE_NONE_ROTATING)
3363                                 softc->sort_io_queue = 0;
3364                 } else {
3365                         int error;
3366                         error = daerror(done_ccb, CAM_RETRY_SELTO,
3367                                         SF_RETRY_UA|SF_NO_PRINT);
3368                         if (error == ERESTART)
3369                                 return;
3370                         else if (error != 0) {
3371                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3372                                         /* Don't wedge this device's queue */
3373                                         cam_release_devq(done_ccb->ccb_h.path,
3374                                                          /*relsim_flags*/0,
3375                                                          /*reduction*/0,
3376                                                          /*timeout*/0,
3377                                                          /*getcount_only*/0);
3378                                 }
3379                         }
3380                 }
3381
3382                 free(bdc, M_SCSIDA);
3383                 xpt_release_ccb(done_ccb);
3384                 softc->state = DA_STATE_PROBE_ATA;
3385                 xpt_schedule(periph, priority);
3386                 return;
3387         }
3388         case DA_CCB_PROBE_ATA:
3389         {
3390                 int i;
3391                 struct ata_params *ata_params;
3392                 int16_t *ptr;
3393
3394                 ata_params = (struct ata_params *)csio->data_ptr;
3395                 ptr = (uint16_t *)ata_params;
3396
3397                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3398                         for (i = 0; i < sizeof(*ata_params) / 2; i++)
3399                                 ptr[i] = le16toh(ptr[i]);
3400                         if (ata_params->support_dsm & ATA_SUPPORT_DSM_TRIM) {
3401                                 dadeleteflag(softc, DA_DELETE_ATA_TRIM, 1);
3402                                 if (ata_params->max_dsm_blocks != 0)
3403                                         softc->trim_max_ranges = min(
3404                                           softc->trim_max_ranges,
3405                                           ata_params->max_dsm_blocks *
3406                                           ATA_DSM_BLK_RANGES);
3407                         }
3408                         /*
3409                          * Disable queue sorting for non-rotational media
3410                          * by default.
3411                          */
3412                         if (ata_params->media_rotation_rate == 1)
3413                                 softc->sort_io_queue = 0;
3414                 } else {
3415                         int error;
3416                         error = daerror(done_ccb, CAM_RETRY_SELTO,
3417                                         SF_RETRY_UA|SF_NO_PRINT);
3418                         if (error == ERESTART)
3419                                 return;
3420                         else if (error != 0) {
3421                                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3422                                         /* Don't wedge this device's queue */
3423                                         cam_release_devq(done_ccb->ccb_h.path,
3424                                                          /*relsim_flags*/0,
3425                                                          /*reduction*/0,
3426                                                          /*timeout*/0,
3427                                                          /*getcount_only*/0);
3428                                 }
3429                         }
3430                 }
3431
3432                 free(ata_params, M_SCSIDA);
3433                 daprobedone(periph, done_ccb);
3434                 return;
3435         }
3436         case DA_CCB_WAITING:
3437         {
3438                 /* Caller will release the CCB */
3439                 wakeup(&done_ccb->ccb_h.cbfcnp);
3440                 return;
3441         }
3442         case DA_CCB_DUMP:
3443                 /* No-op.  We're polling */
3444                 return;
3445         case DA_CCB_TUR:
3446         {
3447                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3448
3449                         if (daerror(done_ccb, CAM_RETRY_SELTO,
3450                             SF_RETRY_UA | SF_NO_RECOVERY | SF_NO_PRINT) ==
3451                             ERESTART)
3452                                 return;
3453                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
3454                                 cam_release_devq(done_ccb->ccb_h.path,
3455                                                  /*relsim_flags*/0,
3456                                                  /*reduction*/0,
3457                                                  /*timeout*/0,
3458                                                  /*getcount_only*/0);
3459                 }
3460                 xpt_release_ccb(done_ccb);
3461                 cam_periph_release_locked(periph);
3462                 return;
3463         }
3464         default:
3465                 break;
3466         }
3467         xpt_release_ccb(done_ccb);
3468 }
3469
3470 static void
3471 dareprobe(struct cam_periph *periph)
3472 {
3473         struct da_softc   *softc;
3474         cam_status status;
3475
3476         softc = (struct da_softc *)periph->softc;
3477
3478         /* Probe in progress; don't interfere. */
3479         if (softc->state != DA_STATE_NORMAL)
3480                 return;
3481
3482         status = cam_periph_acquire(periph);
3483         KASSERT(status == CAM_REQ_CMP,
3484             ("dareprobe: cam_periph_acquire failed"));
3485
3486         if (softc->flags & DA_FLAG_CAN_RC16)
3487                 softc->state = DA_STATE_PROBE_RC16;
3488         else
3489                 softc->state = DA_STATE_PROBE_RC;
3490
3491         xpt_schedule(periph, CAM_PRIORITY_DEV);
3492 }
3493
3494 static int
3495 daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
3496 {
3497         struct da_softc   *softc;
3498         struct cam_periph *periph;
3499         int error, error_code, sense_key, asc, ascq;
3500
3501         periph = xpt_path_periph(ccb->ccb_h.path);
3502         softc = (struct da_softc *)periph->softc;
3503
3504         /*
3505          * Automatically detect devices that do not support
3506          * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
3507          */
3508         error = 0;
3509         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
3510                 error = cmd6workaround(ccb);
3511         } else if (scsi_extract_sense_ccb(ccb,
3512             &error_code, &sense_key, &asc, &ascq)) {
3513                 if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
3514                         error = cmd6workaround(ccb);
3515                 /*
3516                  * If the target replied with CAPACITY DATA HAS CHANGED UA,
3517                  * query the capacity and notify upper layers.
3518                  */
3519                 else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
3520                     asc == 0x2A && ascq == 0x09) {
3521                         xpt_print(periph->path, "capacity data has changed\n");
3522                         dareprobe(periph);
3523                         sense_flags |= SF_NO_PRINT;
3524                 } else if (sense_key == SSD_KEY_UNIT_ATTENTION &&
3525                     asc == 0x28 && ascq == 0x00)
3526                         disk_media_changed(softc->disk, M_NOWAIT);
3527                 else if (sense_key == SSD_KEY_NOT_READY &&
3528                     asc == 0x3a && (softc->flags & DA_FLAG_SAW_MEDIA)) {
3529                         softc->flags &= ~DA_FLAG_SAW_MEDIA;
3530                         disk_media_gone(softc->disk, M_NOWAIT);
3531                 }
3532         }
3533         if (error == ERESTART)
3534                 return (ERESTART);
3535
3536         /*
3537          * XXX
3538          * Until we have a better way of doing pack validation,
3539          * don't treat UAs as errors.
3540          */
3541         sense_flags |= SF_RETRY_UA;
3542         return(cam_periph_error(ccb, cam_flags, sense_flags,
3543                                 &softc->saved_ccb));
3544 }
3545
3546 static void
3547 damediapoll(void *arg)
3548 {
3549         struct cam_periph *periph = arg;
3550         struct da_softc *softc = periph->softc;
3551
3552         if (!softc->tur && softc->outstanding_cmds == 0) {
3553                 if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
3554                         softc->tur = 1;
3555                         daschedule(periph);
3556                 }
3557         }
3558         /* Queue us up again */
3559         if (da_poll_period != 0)
3560                 callout_schedule(&softc->mediapoll_c, da_poll_period * hz);
3561 }
3562
3563 static void
3564 daprevent(struct cam_periph *periph, int action)
3565 {
3566         struct  da_softc *softc;
3567         union   ccb *ccb;               
3568         int     error;
3569                 
3570         softc = (struct da_softc *)periph->softc;
3571
3572         if (((action == PR_ALLOW)
3573           && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
3574          || ((action == PR_PREVENT)
3575           && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
3576                 return;
3577         }
3578
3579         ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
3580
3581         scsi_prevent(&ccb->csio,
3582                      /*retries*/1,
3583                      /*cbcfp*/dadone,
3584                      MSG_SIMPLE_Q_TAG,
3585                      action,
3586                      SSD_FULL_SIZE,
3587                      5000);
3588
3589         error = cam_periph_runccb(ccb, daerror, CAM_RETRY_SELTO,
3590             SF_RETRY_UA | SF_QUIET_IR, softc->disk->d_devstat);
3591
3592         if (error == 0) {
3593                 if (action == PR_ALLOW)
3594                         softc->flags &= ~DA_FLAG_PACK_LOCKED;
3595                 else
3596                         softc->flags |= DA_FLAG_PACK_LOCKED;
3597         }
3598
3599         xpt_release_ccb(ccb);
3600 }
3601
3602 static void
3603 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
3604           struct scsi_read_capacity_data_long *rcaplong, size_t rcap_len)
3605 {
3606         struct ccb_calc_geometry ccg;
3607         struct da_softc *softc;
3608         struct disk_params *dp;
3609         u_int lbppbe, lalba;
3610
3611         softc = (struct da_softc *)periph->softc;
3612
3613         dp = &softc->params;
3614         dp->secsize = block_len;
3615         dp->sectors = maxsector + 1;
3616         if (rcaplong != NULL) {
3617                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
3618                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
3619                 lalba &= SRC16_LALBA_A;
3620         } else {
3621                 lbppbe = 0;
3622                 lalba = 0;
3623         }
3624
3625         if (lbppbe > 0) {
3626                 dp->stripesize = block_len << lbppbe;
3627                 dp->stripeoffset = (dp->stripesize - block_len * lalba) %
3628                     dp->stripesize;
3629         } else if (softc->quirks & DA_Q_4K) {
3630                 dp->stripesize = 4096;
3631                 dp->stripeoffset = 0;
3632         } else {
3633                 dp->stripesize = 0;
3634                 dp->stripeoffset = 0;
3635         }
3636         /*
3637          * Have the controller provide us with a geometry
3638          * for this disk.  The only time the geometry
3639          * matters is when we boot and the controller
3640          * is the only one knowledgeable enough to come
3641          * up with something that will make this a bootable
3642          * device.
3643          */
3644         xpt_setup_ccb(&ccg.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
3645         ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
3646         ccg.block_size = dp->secsize;
3647         ccg.volume_size = dp->sectors;
3648         ccg.heads = 0;
3649         ccg.secs_per_track = 0;
3650         ccg.cylinders = 0;
3651         xpt_action((union ccb*)&ccg);
3652         if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3653                 /*
3654                  * We don't know what went wrong here- but just pick
3655                  * a geometry so we don't have nasty things like divide
3656                  * by zero.
3657                  */
3658                 dp->heads = 255;
3659                 dp->secs_per_track = 255;
3660                 dp->cylinders = dp->sectors / (255 * 255);
3661                 if (dp->cylinders == 0) {
3662                         dp->cylinders = 1;
3663                 }
3664         } else {
3665                 dp->heads = ccg.heads;
3666                 dp->secs_per_track = ccg.secs_per_track;
3667                 dp->cylinders = ccg.cylinders;
3668         }
3669
3670         /*
3671          * If the user supplied a read capacity buffer, and if it is
3672          * different than the previous buffer, update the data in the EDT.
3673          * If it's the same, we don't bother.  This avoids sending an
3674          * update every time someone opens this device.
3675          */
3676         if ((rcaplong != NULL)
3677          && (bcmp(rcaplong, &softc->rcaplong,
3678                   min(sizeof(softc->rcaplong), rcap_len)) != 0)) {
3679                 struct ccb_dev_advinfo cdai;
3680
3681                 xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
3682                 cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
3683                 cdai.buftype = CDAI_TYPE_RCAPLONG;
3684                 cdai.flags |= CDAI_FLAG_STORE;
3685                 cdai.bufsiz = rcap_len;
3686                 cdai.buf = (uint8_t *)rcaplong;
3687                 xpt_action((union ccb *)&cdai);
3688                 if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
3689                         cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
3690                 if (cdai.ccb_h.status != CAM_REQ_CMP) {
3691                         xpt_print(periph->path, "%s: failed to set read "
3692                                   "capacity advinfo\n", __func__);
3693                         /* Use cam_error_print() to decode the status */
3694                         cam_error_print((union ccb *)&cdai, CAM_ESF_CAM_STATUS,
3695                                         CAM_EPF_ALL);
3696                 } else {
3697                         bcopy(rcaplong, &softc->rcaplong,
3698                               min(sizeof(softc->rcaplong), rcap_len));
3699                 }
3700         }
3701
3702         softc->disk->d_sectorsize = softc->params.secsize;
3703         softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
3704         softc->disk->d_stripesize = softc->params.stripesize;
3705         softc->disk->d_stripeoffset = softc->params.stripeoffset;
3706         /* XXX: these are not actually "firmware" values, so they may be wrong */
3707         softc->disk->d_fwsectors = softc->params.secs_per_track;
3708         softc->disk->d_fwheads = softc->params.heads;
3709         softc->disk->d_devstat->block_size = softc->params.secsize;
3710         softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
3711 }
3712
3713 static void
3714 dasendorderedtag(void *arg)
3715 {
3716         struct da_softc *softc = arg;
3717
3718         if (da_send_ordered) {
3719                 if ((softc->ordered_tag_count == 0) 
3720                  && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
3721                         softc->flags |= DA_FLAG_NEED_OTAG;
3722                 }
3723                 if (softc->outstanding_cmds > 0)
3724                         softc->flags &= ~DA_FLAG_WENT_IDLE;
3725
3726                 softc->ordered_tag_count = 0;
3727         }
3728         /* Queue us up again */
3729         callout_reset(&softc->sendordered_c,
3730             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
3731             dasendorderedtag, softc);
3732 }
3733
3734 /*
3735  * Step through all DA peripheral drivers, and if the device is still open,
3736  * sync the disk cache to physical media.
3737  */
3738 static void
3739 dashutdown(void * arg, int howto)
3740 {
3741         struct cam_periph *periph;
3742         struct da_softc *softc;
3743         union ccb *ccb;
3744         int error;
3745
3746         CAM_PERIPH_FOREACH(periph, &dadriver) {
3747                 softc = (struct da_softc *)periph->softc;
3748                 if (SCHEDULER_STOPPED()) {
3749                         /* If we paniced with the lock held, do not recurse. */
3750                         if (!cam_periph_owned(periph) &&
3751                             (softc->flags & DA_FLAG_OPEN)) {
3752                                 dadump(softc->disk, NULL, 0, 0, 0);
3753                         }
3754                         continue;
3755                 }
3756                 cam_periph_lock(periph);
3757
3758                 /*
3759                  * We only sync the cache if the drive is still open, and
3760                  * if the drive is capable of it..
3761                  */
3762                 if (((softc->flags & DA_FLAG_OPEN) == 0)
3763                  || (softc->quirks & DA_Q_NO_SYNC_CACHE)) {
3764                         cam_periph_unlock(periph);
3765                         continue;
3766                 }
3767
3768                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
3769                 scsi_synchronize_cache(&ccb->csio,
3770                                        /*retries*/0,
3771                                        /*cbfcnp*/dadone,
3772                                        MSG_SIMPLE_Q_TAG,
3773                                        /*begin_lba*/0, /* whole disk */
3774                                        /*lb_count*/0,
3775                                        SSD_FULL_SIZE,
3776                                        60 * 60 * 1000);
3777
3778                 error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
3779                     /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR,
3780                     softc->disk->d_devstat);
3781                 if (error != 0)
3782                         xpt_print(periph->path, "Synchronize cache failed\n");
3783                 xpt_release_ccb(ccb);
3784                 cam_periph_unlock(periph);
3785         }
3786 }
3787
3788 #else /* !_KERNEL */
3789
3790 /*
3791  * XXX This is only left out of the kernel build to silence warnings.  If,
3792  * for some reason this function is used in the kernel, the ifdefs should
3793  * be moved so it is included both in the kernel and userland.
3794  */
3795 void
3796 scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
3797                  void (*cbfcnp)(struct cam_periph *, union ccb *),
3798                  u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
3799                  u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
3800                  u_int32_t timeout)
3801 {
3802         struct scsi_format_unit *scsi_cmd;
3803
3804         scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
3805         scsi_cmd->opcode = FORMAT_UNIT;
3806         scsi_cmd->byte2 = byte2;
3807         scsi_ulto2b(ileave, scsi_cmd->interleave);
3808
3809         cam_fill_csio(csio,
3810                       retries,
3811                       cbfcnp,
3812                       /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
3813                       tag_action,
3814                       data_ptr,
3815                       dxfer_len,
3816                       sense_len,
3817                       sizeof(*scsi_cmd),
3818                       timeout);
3819 }
3820
3821 #endif /* _KERNEL */