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