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