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