]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/cam/scsi/scsi_da.c
MFC r241580:
[FreeBSD/stable/9.git] / sys / cam / scsi / scsi_da.c
1 /*-
2  * Implementation of SCSI Direct Access Peripheral driver for CAM.
3  *
4  * Copyright (c) 1997 Justin T. Gibbs.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions, and the following disclaimer,
12  *    without modification, immediately at the beginning of the file.
13  * 2. The name of the author may not be used to endorse or promote products
14  *    derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33
34 #ifdef _KERNEL
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/bio.h>
38 #include <sys/sysctl.h>
39 #include <sys/taskqueue.h>
40 #include <sys/lock.h>
41 #include <sys/mutex.h>
42 #include <sys/conf.h>
43 #include <sys/devicestat.h>
44 #include <sys/eventhandler.h>
45 #include <sys/malloc.h>
46 #include <sys/cons.h>
47 #include <geom/geom.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,
71         DA_STATE_PROBE2,
72         DA_STATE_NORMAL
73 } da_state;
74
75 typedef enum {
76         DA_FLAG_PACK_INVALID    = 0x001,
77         DA_FLAG_NEW_PACK        = 0x002,
78         DA_FLAG_PACK_LOCKED     = 0x004,
79         DA_FLAG_PACK_REMOVABLE  = 0x008,
80         DA_FLAG_NEED_OTAG       = 0x020,
81         DA_FLAG_WENT_IDLE       = 0x040,
82         DA_FLAG_RETRY_UA        = 0x080,
83         DA_FLAG_OPEN            = 0x100,
84         DA_FLAG_SCTX_INIT       = 0x200,
85         DA_FLAG_CAN_RC16        = 0x400
86 } da_flags;
87
88 typedef enum {
89         DA_Q_NONE               = 0x00,
90         DA_Q_NO_SYNC_CACHE      = 0x01,
91         DA_Q_NO_6_BYTE          = 0x02,
92         DA_Q_NO_PREVENT         = 0x04,
93         DA_Q_4K                 = 0x08
94 } da_quirks;
95
96 typedef enum {
97         DA_CCB_PROBE            = 0x01,
98         DA_CCB_PROBE2           = 0x02,
99         DA_CCB_BUFFER_IO        = 0x03,
100         DA_CCB_WAITING          = 0x04,
101         DA_CCB_DUMP             = 0x05,
102         DA_CCB_DELETE           = 0x06,
103         DA_CCB_TYPE_MASK        = 0x0F,
104         DA_CCB_RETRY_UA         = 0x10
105 } da_ccb_state;
106
107 typedef enum {
108         DA_DELETE_NONE,
109         DA_DELETE_DISABLE,
110         DA_DELETE_ZERO,
111         DA_DELETE_WS10,
112         DA_DELETE_WS16,
113         DA_DELETE_UNMAP,
114         DA_DELETE_MAX = DA_DELETE_UNMAP
115 } da_delete_methods;
116
117 static const char *da_delete_method_names[] =
118     { "NONE", "DISABLE", "ZERO", "WS10", "WS16", "UNMAP" };
119
120 /* Offsets into our private area for storing information */
121 #define ccb_state       ppriv_field0
122 #define ccb_bp          ppriv_ptr1
123
124 struct disk_params {
125         u_int8_t  heads;
126         u_int32_t cylinders;
127         u_int8_t  secs_per_track;
128         u_int32_t secsize;      /* Number of bytes/sector */
129         u_int64_t sectors;      /* total number sectors */
130         u_int     stripesize;
131         u_int     stripeoffset;
132 };
133
134 #define UNMAP_MAX_RANGES        512
135
136 struct da_softc {
137         struct   bio_queue_head bio_queue;
138         struct   bio_queue_head delete_queue;
139         struct   bio_queue_head delete_run_queue;
140         SLIST_ENTRY(da_softc) links;
141         LIST_HEAD(, ccb_hdr) pending_ccbs;
142         da_state state;
143         da_flags flags; 
144         da_quirks quirks;
145         int      minimum_cmd_size;
146         int      error_inject;
147         int      ordered_tag_count;
148         int      outstanding_cmds;
149         int      unmap_max_ranges;
150         int      unmap_max_lba;
151         int      delete_running;
152         da_delete_methods        delete_method;
153         struct   disk_params params;
154         struct   disk *disk;
155         union    ccb saved_ccb;
156         struct task             sysctl_task;
157         struct sysctl_ctx_list  sysctl_ctx;
158         struct sysctl_oid       *sysctl_tree;
159         struct callout          sendordered_c;
160         uint64_t wwpn;
161         uint8_t  unmap_buf[UNMAP_MAX_RANGES * 16 + 8];
162 };
163
164 struct da_quirk_entry {
165         struct scsi_inquiry_pattern inq_pat;
166         da_quirks quirks;
167 };
168
169 static const char quantum[] = "QUANTUM";
170 static const char microp[] = "MICROP";
171
172 static struct da_quirk_entry da_quirk_table[] =
173 {
174         /* SPI, FC devices */
175         {
176                 /*
177                  * Fujitsu M2513A MO drives.
178                  * Tested devices: M2513A2 firmware versions 1200 & 1300.
179                  * (dip switch selects whether T_DIRECT or T_OPTICAL device)
180                  * Reported by: W.Scholten <whs@xs4all.nl>
181                  */
182                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
183                 /*quirks*/ DA_Q_NO_SYNC_CACHE
184         },
185         {
186                 /* See above. */
187                 {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
188                 /*quirks*/ DA_Q_NO_SYNC_CACHE
189         },
190         {
191                 /*
192                  * This particular Fujitsu drive doesn't like the
193                  * synchronize cache command.
194                  * Reported by: Tom Jackson <toj@gorilla.net>
195                  */
196                 {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
197                 /*quirks*/ DA_Q_NO_SYNC_CACHE
198         },
199         {
200                 /*
201                  * This drive doesn't like the synchronize cache command
202                  * either.  Reported by: Matthew Jacob <mjacob@feral.com>
203                  * in NetBSD PR kern/6027, August 24, 1998.
204                  */
205                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
206                 /*quirks*/ DA_Q_NO_SYNC_CACHE
207         },
208         {
209                 /*
210                  * This drive doesn't like the synchronize cache command
211                  * either.  Reported by: Hellmuth Michaelis (hm@kts.org)
212                  * (PR 8882).
213                  */
214                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
215                 /*quirks*/ DA_Q_NO_SYNC_CACHE
216         },
217         {
218                 /*
219                  * Doesn't like the synchronize cache command.
220                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
221                  */
222                 {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
223                 /*quirks*/ DA_Q_NO_SYNC_CACHE
224         },
225         {
226                 /*
227                  * Doesn't like the synchronize cache command.
228                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
229                  */
230                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
231                 /*quirks*/ DA_Q_NO_SYNC_CACHE
232         },
233         {
234                 /*
235                  * Doesn't like the synchronize cache command.
236                  */
237                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
238                 /*quirks*/ DA_Q_NO_SYNC_CACHE
239         },
240         {
241                 /*
242                  * Doesn't like the synchronize cache command.
243                  * Reported by: walter@pelissero.de
244                  */
245                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
246                 /*quirks*/ DA_Q_NO_SYNC_CACHE
247         },
248         {
249                 /*
250                  * Doesn't work correctly with 6 byte reads/writes.
251                  * Returns illegal request, and points to byte 9 of the
252                  * 6-byte CDB.
253                  * Reported by:  Adam McDougall <bsdx@spawnet.com>
254                  */
255                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
256                 /*quirks*/ DA_Q_NO_6_BYTE
257         },
258         {
259                 /* See above. */
260                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
261                 /*quirks*/ DA_Q_NO_6_BYTE
262         },
263         {
264                 /*
265                  * Doesn't like the synchronize cache command.
266                  * Reported by: walter@pelissero.de
267                  */
268                 {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
269                 /*quirks*/ DA_Q_NO_SYNC_CACHE
270         },
271         {
272                 /*
273                  * The CISS RAID controllers do not support SYNC_CACHE
274                  */
275                 {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
276                 /*quirks*/ DA_Q_NO_SYNC_CACHE
277         },
278         /* USB mass storage devices supported by umass(4) */
279         {
280                 /*
281                  * EXATELECOM (Sigmatel) i-Bead 100/105 USB Flash MP3 Player
282                  * PR: kern/51675
283                  */
284                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EXATEL", "i-BEAD10*", "*"},
285                 /*quirks*/ DA_Q_NO_SYNC_CACHE
286         },
287         {
288                 /*
289                  * Power Quotient Int. (PQI) USB flash key
290                  * PR: kern/53067
291                  */
292                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "USB Flash Disk*",
293                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
294         },
295         {
296                 /*
297                  * Creative Nomad MUVO mp3 player (USB)
298                  * PR: kern/53094
299                  */
300                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
301                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
302         },
303         {
304                 /*
305                  * Jungsoft NEXDISK USB flash key
306                  * PR: kern/54737
307                  */
308                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JUNGSOFT", "NEXDISK*", "*"},
309                 /*quirks*/ DA_Q_NO_SYNC_CACHE
310         },
311         {
312                 /*
313                  * FreeDik USB Mini Data Drive
314                  * PR: kern/54786
315                  */
316                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FreeDik*", "Mini Data Drive",
317                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
318         },
319         {
320                 /*
321                  * Sigmatel USB Flash MP3 Player
322                  * PR: kern/57046
323                  */
324                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
325                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
326         },
327         {
328                 /*
329                  * Neuros USB Digital Audio Computer
330                  * PR: kern/63645
331                  */
332                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "NEUROS", "dig. audio comp.",
333                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
334         },
335         {
336                 /*
337                  * SEAGRAND NP-900 MP3 Player
338                  * PR: kern/64563
339                  */
340                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
341                 /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
342         },
343         {
344                 /*
345                  * iRiver iFP MP3 player (with UMS Firmware)
346                  * PR: kern/54881, i386/63941, kern/66124
347                  */
348                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iRiver", "iFP*", "*"},
349                 /*quirks*/ DA_Q_NO_SYNC_CACHE
350         },
351         {
352                 /*
353                  * Frontier Labs NEX IA+ Digital Audio Player, rev 1.10/0.01
354                  * PR: kern/70158
355                  */
356                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FL" , "Nex*", "*"},
357                 /*quirks*/ DA_Q_NO_SYNC_CACHE
358         },
359         {
360                 /*
361                  * ZICPlay USB MP3 Player with FM
362                  * PR: kern/75057
363                  */
364                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ACTIONS*" , "USB DISK*", "*"},
365                 /*quirks*/ DA_Q_NO_SYNC_CACHE
366         },
367         {
368                 /*
369                  * TEAC USB floppy mechanisms
370                  */
371                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TEAC" , "FD-05*", "*"},
372                 /*quirks*/ DA_Q_NO_SYNC_CACHE
373         },
374         {
375                 /*
376                  * Kingston DataTraveler II+ USB Pen-Drive.
377                  * Reported by: Pawel Jakub Dawidek <pjd@FreeBSD.org>
378                  */
379                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston" , "DataTraveler II+",
380                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
381         },
382         {
383                 /*
384                  * USB DISK Pro PMAP
385                  * Reported by: jhs
386                  * PR: usb/96381
387                  */
388                 {T_DIRECT, SIP_MEDIA_REMOVABLE, " ", "USB DISK Pro", "PMAP"},
389                 /*quirks*/ DA_Q_NO_SYNC_CACHE
390         },
391         {
392                 /*
393                  * Motorola E398 Mobile Phone (TransFlash memory card).
394                  * Reported by: Wojciech A. Koszek <dunstan@FreeBSD.czest.pl>
395                  * PR: usb/89889
396                  */
397                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Motorola" , "Motorola Phone",
398                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
399         },
400         {
401                 /*
402                  * Qware BeatZkey! Pro
403                  * PR: usb/79164
404                  */
405                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "GENERIC", "USB DISK DEVICE",
406                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
407         },
408         {
409                 /*
410                  * Time DPA20B 1GB MP3 Player
411                  * PR: usb/81846
412                  */
413                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB2.0*", "(FS) FLASH DISK*",
414                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
415         },
416         {
417                 /*
418                  * Samsung USB key 128Mb
419                  * PR: usb/90081
420                  */
421                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB-DISK", "FreeDik-FlashUsb",
422                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
423         },
424         {
425                 /*
426                  * Kingston DataTraveler 2.0 USB Flash memory.
427                  * PR: usb/89196
428                  */
429                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Kingston", "DataTraveler 2.0",
430                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
431         },
432         {
433                 /*
434                  * Creative MUVO Slim mp3 player (USB)
435                  * PR: usb/86131
436                  */
437                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
438                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE|DA_Q_NO_PREVENT
439                 },
440         {
441                 /*
442                  * United MP5512 Portable MP3 Player (2-in-1 USB DISK/MP3)
443                  * PR: usb/80487
444                  */
445                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "MUSIC DISK",
446                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
447         },
448         {
449                 /*
450                  * SanDisk Micro Cruzer 128MB
451                  * PR: usb/75970
452                  */
453                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SanDisk" , "Micro Cruzer",
454                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
455         },
456         {
457                 /*
458                  * TOSHIBA TransMemory USB sticks
459                  * PR: kern/94660
460                  */
461                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "TOSHIBA", "TransMemory",
462                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
463         },
464         {
465                 /*
466                  * PNY USB Flash keys
467                  * PR: usb/75578, usb/72344, usb/65436 
468                  */
469                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
470                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
471         },
472         {
473                 /*
474                  * Genesys 6-in-1 Card Reader
475                  * PR: usb/94647
476                  */
477                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
478                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
479         },
480         {
481                 /*
482                  * Rekam Digital CAMERA
483                  * PR: usb/98713
484                  */
485                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CAMERA*", "4MP-9J6*",
486                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
487         },
488         {
489                 /*
490                  * iRiver H10 MP3 player
491                  * PR: usb/102547
492                  */
493                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "H10*",
494                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
495         },
496         {
497                 /*
498                  * iRiver U10 MP3 player
499                  * PR: usb/92306
500                  */
501                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "iriver", "U10*",
502                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
503         },
504         {
505                 /*
506                  * X-Micro Flash Disk
507                  * PR: usb/96901
508                  */
509                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "X-Micro", "Flash Disk",
510                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
511         },
512         {
513                 /*
514                  * EasyMP3 EM732X USB 2.0 Flash MP3 Player
515                  * PR: usb/96546
516                  */
517                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "EM732X", "MP3 Player*",
518                 "1.00"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
519         },
520         {
521                 /*
522                  * Denver MP3 player
523                  * PR: usb/107101
524                  */
525                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "DENVER", "MP3 PLAYER",
526                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
527         },
528         {
529                 /*
530                  * Philips USB Key Audio KEY013
531                  * PR: usb/68412
532                  */
533                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "PHILIPS", "Key*", "*"},
534                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
535         },
536         {
537                 /*
538                  * JNC MP3 Player
539                  * PR: usb/94439
540                  */
541                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "JNC*" , "MP3 Player*",
542                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
543         },
544         {
545                 /*
546                  * SAMSUNG MP0402H
547                  * PR: usb/108427
548                  */
549                 {T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "MP0402H", "*"},
550                 /*quirks*/ DA_Q_NO_SYNC_CACHE
551         },
552         {
553                 /*
554                  * I/O Magic USB flash - Giga Bank
555                  * PR: usb/108810
556                  */
557                 {T_DIRECT, SIP_MEDIA_FIXED, "GS-Magic", "stor*", "*"},
558                 /*quirks*/ DA_Q_NO_SYNC_CACHE
559         },
560         {
561                 /*
562                  * JoyFly 128mb USB Flash Drive
563                  * PR: 96133
564                  */
565                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "Flash Disk*",
566                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
567         },
568         {
569                 /*
570                  * ChipsBnk usb stick
571                  * PR: 103702
572                  */
573                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "ChipsBnk", "USB*",
574                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
575         },
576         {
577                 /*
578                  * Storcase (Kingston) InfoStation IFS FC2/SATA-R 201A
579                  * PR: 129858
580                  */
581                 {T_DIRECT, SIP_MEDIA_FIXED, "IFS", "FC2/SATA-R*",
582                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
583         },
584         {
585                 /*
586                  * Samsung YP-U3 mp3-player
587                  * PR: 125398
588                  */
589                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Samsung", "YP-U3",
590                  "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
591         },
592         {
593                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Netac", "OnlyDisk*",
594                  "2000"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
595         },
596         {
597                 /*
598                  * Sony Cyber-Shot DSC cameras
599                  * PR: usb/137035
600                  */
601                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "Sony", "Sony DSC", "*"},
602                 /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_NO_PREVENT
603         },
604         /* ATA/SATA devices over SAS/USB/... */
605         {
606                 /* Hitachi Advanced Format (4k) drives */
607                 { T_DIRECT, SIP_MEDIA_FIXED, "Hitachi", "H??????????E3*", "*" },
608                 /*quirks*/DA_Q_4K
609         },
610         {
611                 /* Samsung Advanced Format (4k) drives */
612                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD155UI*", "*" },
613                 /*quirks*/DA_Q_4K
614         },
615         {
616                 /* Samsung Advanced Format (4k) drives */
617                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD155UI*", "*" },
618                 /*quirks*/DA_Q_4K
619         },
620         {
621                 /* Samsung Advanced Format (4k) drives */
622                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "SAMSUNG HD204UI*", "*" },
623                 /*quirks*/DA_Q_4K
624         },
625         {
626                 /* Samsung Advanced Format (4k) drives */
627                 { T_DIRECT, SIP_MEDIA_FIXED, "SAMSUNG", "HD204UI*", "*" },
628                 /*quirks*/DA_Q_4K
629         },
630         {
631                 /* Seagate Barracuda Green Advanced Format (4k) drives */
632                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DL*", "*" },
633                 /*quirks*/DA_Q_4K
634         },
635         {
636                 /* Seagate Barracuda Green Advanced Format (4k) drives */
637                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DL", "*", "*" },
638                 /*quirks*/DA_Q_4K
639         },
640         {
641                 /* Seagate Barracuda Green Advanced Format (4k) drives */
642                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???DM*", "*" },
643                 /*quirks*/DA_Q_4K
644         },
645         {
646                 /* Seagate Barracuda Green Advanced Format (4k) drives */
647                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???DM*", "*", "*" },
648                 /*quirks*/DA_Q_4K
649         },
650         {
651                 /* Seagate Barracuda Green Advanced Format (4k) drives */
652                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST????DM*", "*" },
653                 /*quirks*/DA_Q_4K
654         },
655         {
656                 /* Seagate Barracuda Green Advanced Format (4k) drives */
657                 { T_DIRECT, SIP_MEDIA_FIXED, "ST????DM", "*", "*" },
658                 /*quirks*/DA_Q_4K
659         },
660         {
661                 /* Seagate Momentus Advanced Format (4k) drives */
662                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500423AS*", "*" },
663                 /*quirks*/DA_Q_4K
664         },
665         {
666                 /* Seagate Momentus Advanced Format (4k) drives */
667                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "3AS*", "*" },
668                 /*quirks*/DA_Q_4K
669         },
670         {
671                 /* Seagate Momentus Advanced Format (4k) drives */
672                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9500424AS*", "*" },
673                 /*quirks*/DA_Q_4K
674         },
675         {
676                 /* Seagate Momentus Advanced Format (4k) drives */
677                 { T_DIRECT, SIP_MEDIA_FIXED, "ST950042", "4AS*", "*" },
678                 /*quirks*/DA_Q_4K
679         },
680         {
681                 /* Seagate Momentus Advanced Format (4k) drives */
682                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640423AS*", "*" },
683                 /*quirks*/DA_Q_4K
684         },
685         {
686                 /* Seagate Momentus Advanced Format (4k) drives */
687                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "3AS*", "*" },
688                 /*quirks*/DA_Q_4K
689         },
690         {
691                 /* Seagate Momentus Advanced Format (4k) drives */
692                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9640424AS*", "*" },
693                 /*quirks*/DA_Q_4K
694         },
695         {
696                 /* Seagate Momentus Advanced Format (4k) drives */
697                 { T_DIRECT, SIP_MEDIA_FIXED, "ST964042", "4AS*", "*" },
698                 /*quirks*/DA_Q_4K
699         },
700         {
701                 /* Seagate Momentus Advanced Format (4k) drives */
702                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750420AS*", "*" },
703                 /*quirks*/DA_Q_4K
704         },
705         {
706                 /* Seagate Momentus Advanced Format (4k) drives */
707                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "0AS*", "*" },
708                 /*quirks*/DA_Q_4K
709         },
710         {
711                 /* Seagate Momentus Advanced Format (4k) drives */
712                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750422AS*", "*" },
713                 /*quirks*/DA_Q_4K
714         },
715         {
716                 /* Seagate Momentus Advanced Format (4k) drives */
717                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "2AS*", "*" },
718                 /*quirks*/DA_Q_4K
719         },
720         {
721                 /* Seagate Momentus Advanced Format (4k) drives */
722                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST9750423AS*", "*" },
723                 /*quirks*/DA_Q_4K
724         },
725         {
726                 /* Seagate Momentus Advanced Format (4k) drives */
727                 { T_DIRECT, SIP_MEDIA_FIXED, "ST975042", "3AS*", "*" },
728                 /*quirks*/DA_Q_4K
729         },
730         {
731                 /* Seagate Momentus Thin Advanced Format (4k) drives */
732                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "ST???LT*", "*" },
733                 /*quirks*/DA_Q_4K
734         },
735         {
736                 /* Seagate Momentus Thin Advanced Format (4k) drives */
737                 { T_DIRECT, SIP_MEDIA_FIXED, "ST???LT*", "*", "*" },
738                 /*quirks*/DA_Q_4K
739         },
740         {
741                 /* WDC Caviar Green Advanced Format (4k) drives */
742                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RS*", "*" },
743                 /*quirks*/DA_Q_4K
744         },
745         {
746                 /* WDC Caviar Green Advanced Format (4k) drives */
747                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RS*", "*" },
748                 /*quirks*/DA_Q_4K
749         },
750         {
751                 /* WDC Caviar Green Advanced Format (4k) drives */
752                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD????RX*", "*" },
753                 /*quirks*/DA_Q_4K
754         },
755         {
756                 /* WDC Caviar Green Advanced Format (4k) drives */
757                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "??RX*", "*" },
758                 /*quirks*/DA_Q_4K
759         },
760         {
761                 /* WDC Caviar Green Advanced Format (4k) drives */
762                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RS*", "*" },
763                 /*quirks*/DA_Q_4K
764         },
765         {
766                 /* WDC Caviar Green Advanced Format (4k) drives */
767                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RS*", "*" },
768                 /*quirks*/DA_Q_4K
769         },
770         {
771                 /* WDC Caviar Green Advanced Format (4k) drives */
772                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD??????RX*", "*" },
773                 /*quirks*/DA_Q_4K
774         },
775         {
776                 /* WDC Caviar Green Advanced Format (4k) drives */
777                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "????RX*", "*" },
778                 /*quirks*/DA_Q_4K
779         },
780         {
781                 /* WDC Scorpio Black Advanced Format (4k) drives */
782                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PKT*", "*" },
783                 /*quirks*/DA_Q_4K
784         },
785         {
786                 /* WDC Scorpio Black Advanced Format (4k) drives */
787                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PKT*", "*" },
788                 /*quirks*/DA_Q_4K
789         },
790         {
791                 /* WDC Scorpio Black Advanced Format (4k) drives */
792                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PKT*", "*" },
793                 /*quirks*/DA_Q_4K
794         },
795         {
796                 /* WDC Scorpio Black Advanced Format (4k) drives */
797                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PKT*", "*" },
798                 /*quirks*/DA_Q_4K
799         },
800         {
801                 /* WDC Scorpio Blue Advanced Format (4k) drives */
802                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD???PVT*", "*" },
803                 /*quirks*/DA_Q_4K
804         },
805         {
806                 /* WDC Scorpio Blue Advanced Format (4k) drives */
807                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "?PVT*", "*" },
808                 /*quirks*/DA_Q_4K
809         },
810         {
811                 /* WDC Scorpio Blue Advanced Format (4k) drives */
812                 { T_DIRECT, SIP_MEDIA_FIXED, "ATA", "WDC WD?????PVT*", "*" },
813                 /*quirks*/DA_Q_4K
814         },
815         {
816                 /* WDC Scorpio Blue Advanced Format (4k) drives */
817                 { T_DIRECT, SIP_MEDIA_FIXED, "WDC WD??", "???PVT*", "*" },
818                 /*quirks*/DA_Q_4K
819         },
820         {
821                 /*
822                  * Olympus FE-210 camera
823                  */
824                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "OLYMPUS", "FE210*",
825                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
826         },
827         {
828                 /*
829                  * LG UP3S MP3 player
830                  */
831                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "LG", "UP3S",
832                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
833         },
834         {
835                 /*
836                  * Laser MP3-2GA13 MP3 player
837                  */
838                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "USB 2.0", "(HS) Flash Disk",
839                 "*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
840         },
841 };
842
843 static  disk_strategy_t dastrategy;
844 static  dumper_t        dadump;
845 static  periph_init_t   dainit;
846 static  void            daasync(void *callback_arg, u_int32_t code,
847                                 struct cam_path *path, void *arg);
848 static  void            dasysctlinit(void *context, int pending);
849 static  int             dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
850 static  int             dadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
851 static  periph_ctor_t   daregister;
852 static  periph_dtor_t   dacleanup;
853 static  periph_start_t  dastart;
854 static  periph_oninv_t  daoninvalidate;
855 static  void            dadone(struct cam_periph *periph,
856                                union ccb *done_ccb);
857 static  int             daerror(union ccb *ccb, u_int32_t cam_flags,
858                                 u_int32_t sense_flags);
859 static void             daprevent(struct cam_periph *periph, int action);
860 static int              dagetcapacity(struct cam_periph *periph);
861 static void             dasetgeom(struct cam_periph *periph, uint32_t block_len,
862                                   uint64_t maxsector, u_int lbppbe, u_int lalba);
863 static timeout_t        dasendorderedtag;
864 static void             dashutdown(void *arg, int howto);
865
866 #ifndef DA_DEFAULT_TIMEOUT
867 #define DA_DEFAULT_TIMEOUT 60   /* Timeout in seconds */
868 #endif
869
870 #ifndef DA_DEFAULT_RETRY
871 #define DA_DEFAULT_RETRY        4
872 #endif
873
874 #ifndef DA_DEFAULT_SEND_ORDERED
875 #define DA_DEFAULT_SEND_ORDERED 1
876 #endif
877
878
879 static int da_retry_count = DA_DEFAULT_RETRY;
880 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
881 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
882
883 SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
884             "CAM Direct Access Disk driver");
885 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
886            &da_retry_count, 0, "Normal I/O retry count");
887 TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
888 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
889            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
890 TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
891 SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
892            &da_send_ordered, 0, "Send Ordered Tags");
893 TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
894
895 /*
896  * DA_ORDEREDTAG_INTERVAL determines how often, relative
897  * to the default timeout, we check to see whether an ordered
898  * tagged transaction is appropriate to prevent simple tag
899  * starvation.  Since we'd like to ensure that there is at least
900  * 1/2 of the timeout length left for a starved transaction to
901  * complete after we've sent an ordered tag, we must poll at least
902  * four times in every timeout period.  This takes care of the worst
903  * case where a starved transaction starts during an interval that
904  * meets the requirement "don't send an ordered tag" test so it takes
905  * us two intervals to determine that a tag must be sent.
906  */
907 #ifndef DA_ORDEREDTAG_INTERVAL
908 #define DA_ORDEREDTAG_INTERVAL 4
909 #endif
910
911 static struct periph_driver dadriver =
912 {
913         dainit, "da",
914         TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
915 };
916
917 PERIPHDRIVER_DECLARE(da, dadriver);
918
919 MALLOC_DEFINE(M_SCSIDA, "scsi_da", "scsi_da buffers");
920
921 static int
922 daopen(struct disk *dp)
923 {
924         struct cam_periph *periph;
925         struct da_softc *softc;
926         int unit;
927         int error;
928
929         periph = (struct cam_periph *)dp->d_drv1;
930         if (periph == NULL) {
931                 return (ENXIO); 
932         }
933
934         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
935                 return (ENXIO);
936         }
937
938         cam_periph_lock(periph);
939         if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
940                 cam_periph_unlock(periph);
941                 cam_periph_release(periph);
942                 return (error);
943         }
944
945         unit = periph->unit_number;
946         softc = (struct da_softc *)periph->softc;
947         softc->flags |= DA_FLAG_OPEN;
948
949         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
950             ("daopen\n"));
951
952         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
953                 /* Invalidate our pack information. */
954                 softc->flags &= ~DA_FLAG_PACK_INVALID;
955         }
956
957         error = dagetcapacity(periph);
958
959         if (error == 0) {
960
961                 softc->disk->d_sectorsize = softc->params.secsize;
962                 softc->disk->d_mediasize = softc->params.secsize * (off_t)softc->params.sectors;
963                 softc->disk->d_stripesize = softc->params.stripesize;
964                 softc->disk->d_stripeoffset = softc->params.stripeoffset;
965                 /* XXX: these are not actually "firmware" values, so they may be wrong */
966                 softc->disk->d_fwsectors = softc->params.secs_per_track;
967                 softc->disk->d_fwheads = softc->params.heads;
968                 softc->disk->d_devstat->block_size = softc->params.secsize;
969                 softc->disk->d_devstat->flags &= ~DEVSTAT_BS_UNAVAILABLE;
970                 if (softc->delete_method > DA_DELETE_DISABLE)
971                         softc->disk->d_flags |= DISKFLAG_CANDELETE;
972                 else
973                         softc->disk->d_flags &= ~DISKFLAG_CANDELETE;
974
975                 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
976                     (softc->quirks & DA_Q_NO_PREVENT) == 0)
977                         daprevent(periph, PR_PREVENT);
978         } else
979                 softc->flags &= ~DA_FLAG_OPEN;
980
981         cam_periph_unhold(periph);
982         cam_periph_unlock(periph);
983
984         if (error != 0) {
985                 cam_periph_release(periph);
986         }
987         return (error);
988 }
989
990 static int
991 daclose(struct disk *dp)
992 {
993         struct  cam_periph *periph;
994         struct  da_softc *softc;
995
996         periph = (struct cam_periph *)dp->d_drv1;
997         if (periph == NULL)
998                 return (0);     
999
1000         cam_periph_lock(periph);
1001         if (cam_periph_hold(periph, PRIBIO) != 0) {
1002                 cam_periph_unlock(periph);
1003                 cam_periph_release(periph);
1004                 return (0);
1005         }
1006
1007         softc = (struct da_softc *)periph->softc;
1008
1009         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1010             ("daclose\n"));
1011
1012         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0
1013          && (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
1014                 union   ccb *ccb;
1015
1016                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1017
1018                 scsi_synchronize_cache(&ccb->csio,
1019                                        /*retries*/1,
1020                                        /*cbfcnp*/dadone,
1021                                        MSG_SIMPLE_Q_TAG,
1022                                        /*begin_lba*/0,/* Cover the whole disk */
1023                                        /*lb_count*/0,
1024                                        SSD_FULL_SIZE,
1025                                        5 * 60 * 1000);
1026
1027                 cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
1028                                   /*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
1029                                   softc->disk->d_devstat);
1030                 xpt_release_ccb(ccb);
1031
1032         }
1033
1034         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
1035                 if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
1036                         daprevent(periph, PR_ALLOW);
1037                 /*
1038                  * If we've got removeable media, mark the blocksize as
1039                  * unavailable, since it could change when new media is
1040                  * inserted.
1041                  */
1042                 softc->disk->d_devstat->flags |= DEVSTAT_BS_UNAVAILABLE;
1043         }
1044
1045         softc->flags &= ~DA_FLAG_OPEN;
1046         cam_periph_unhold(periph);
1047         cam_periph_unlock(periph);
1048         cam_periph_release(periph);
1049         return (0);     
1050 }
1051
1052 static void
1053 daschedule(struct cam_periph *periph)
1054 {
1055         struct da_softc *softc = (struct da_softc *)periph->softc;
1056         uint32_t prio;
1057
1058         /* Check if cam_periph_getccb() was called. */
1059         prio = periph->immediate_priority;
1060
1061         /* Check if we have more work to do. */
1062         if (bioq_first(&softc->bio_queue) ||
1063             (!softc->delete_running && bioq_first(&softc->delete_queue))) {
1064                 prio = CAM_PRIORITY_NORMAL;
1065         }
1066
1067         /* Schedule CCB if any of above is true. */
1068         if (prio != CAM_PRIORITY_NONE)
1069                 xpt_schedule(periph, prio);
1070 }
1071
1072 /*
1073  * Actually translate the requested transfer into one the physical driver
1074  * can understand.  The transfer is described by a buf and will include
1075  * only one physical transfer.
1076  */
1077 static void
1078 dastrategy(struct bio *bp)
1079 {
1080         struct cam_periph *periph;
1081         struct da_softc *softc;
1082         
1083         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1084         if (periph == NULL) {
1085                 biofinish(bp, NULL, ENXIO);
1086                 return;
1087         }
1088         softc = (struct da_softc *)periph->softc;
1089
1090         cam_periph_lock(periph);
1091
1092         /*
1093          * If the device has been made invalid, error out
1094          */
1095         if ((softc->flags & DA_FLAG_PACK_INVALID)) {
1096                 cam_periph_unlock(periph);
1097                 biofinish(bp, NULL, ENXIO);
1098                 return;
1099         }
1100
1101         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastrategy(%p)\n", bp));
1102
1103         /*
1104          * Place it in the queue of disk activities for this disk
1105          */
1106         if (bp->bio_cmd == BIO_DELETE) {
1107                 if (bp->bio_bcount == 0)
1108                         biodone(bp);
1109                 else
1110                         bioq_disksort(&softc->delete_queue, bp);
1111         } else
1112                 bioq_disksort(&softc->bio_queue, bp);
1113
1114         /*
1115          * Schedule ourselves for performing the work.
1116          */
1117         daschedule(periph);
1118         cam_periph_unlock(periph);
1119
1120         return;
1121 }
1122
1123 static int
1124 dadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
1125 {
1126         struct      cam_periph *periph;
1127         struct      da_softc *softc;
1128         u_int       secsize;
1129         struct      ccb_scsiio csio;
1130         struct      disk *dp;
1131         int         error = 0;
1132
1133         dp = arg;
1134         periph = dp->d_drv1;
1135         if (periph == NULL)
1136                 return (ENXIO);
1137         softc = (struct da_softc *)periph->softc;
1138         cam_periph_lock(periph);
1139         secsize = softc->params.secsize;
1140         
1141         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
1142                 cam_periph_unlock(periph);
1143                 return (ENXIO);
1144         }
1145
1146         if (length > 0) {
1147                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1148                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
1149                 scsi_read_write(&csio,
1150                                 /*retries*/0,
1151                                 dadone,
1152                                 MSG_ORDERED_Q_TAG,
1153                                 /*read*/FALSE,
1154                                 /*byte2*/0,
1155                                 /*minimum_cmd_size*/ softc->minimum_cmd_size,
1156                                 offset / secsize,
1157                                 length / secsize,
1158                                 /*data_ptr*/(u_int8_t *) virtual,
1159                                 /*dxfer_len*/length,
1160                                 /*sense_len*/SSD_FULL_SIZE,
1161                                 da_default_timeout * 1000);
1162                 xpt_polled_action((union ccb *)&csio);
1163
1164                 error = cam_periph_error((union ccb *)&csio,
1165                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1166                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
1167                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
1168                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
1169                 if (error != 0)
1170                         printf("Aborting dump due to I/O error.\n");
1171                 cam_periph_unlock(periph);
1172                 return (error);
1173         }
1174                 
1175         /*
1176          * Sync the disk cache contents to the physical media.
1177          */
1178         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
1179
1180                 xpt_setup_ccb(&csio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1181                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
1182                 scsi_synchronize_cache(&csio,
1183                                        /*retries*/0,
1184                                        /*cbfcnp*/dadone,
1185                                        MSG_SIMPLE_Q_TAG,
1186                                        /*begin_lba*/0,/* Cover the whole disk */
1187                                        /*lb_count*/0,
1188                                        SSD_FULL_SIZE,
1189                                        5 * 60 * 1000);
1190                 xpt_polled_action((union ccb *)&csio);
1191
1192                 error = cam_periph_error((union ccb *)&csio,
1193                     0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
1194                 if ((csio.ccb_h.status & CAM_DEV_QFRZN) != 0)
1195                         cam_release_devq(csio.ccb_h.path, /*relsim_flags*/0,
1196                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
1197                 if (error != 0)
1198                         xpt_print(periph->path, "Synchronize cache failed\n");
1199         }
1200         cam_periph_unlock(periph);
1201         return (error);
1202 }
1203
1204 static int
1205 dagetattr(struct bio *bp)
1206 {
1207         int ret = -1;
1208         struct cam_periph *periph;
1209
1210         if (bp->bio_disk == NULL || bp->bio_disk->d_drv1 == NULL)
1211                 return ENXIO;
1212         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1213         if (periph->path == NULL)
1214                 return ENXIO;
1215
1216         ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
1217             periph->path);
1218         if (ret == 0)
1219                 bp->bio_completed = bp->bio_length;
1220         return ret;
1221 }
1222
1223 static void
1224 dainit(void)
1225 {
1226         cam_status status;
1227
1228         /*
1229          * Install a global async callback.  This callback will
1230          * receive async callbacks like "new device found".
1231          */
1232         status = xpt_register_async(AC_FOUND_DEVICE, daasync, NULL, NULL);
1233
1234         if (status != CAM_REQ_CMP) {
1235                 printf("da: Failed to attach master async callback "
1236                        "due to status 0x%x!\n", status);
1237         } else if (da_send_ordered) {
1238
1239                 /* Register our shutdown event handler */
1240                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 
1241                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
1242                     printf("dainit: shutdown event registration failed!\n");
1243         }
1244 }
1245
1246 /*
1247  * Callback from GEOM, called when it has finished cleaning up its
1248  * resources.
1249  */
1250 static void
1251 dadiskgonecb(struct disk *dp)
1252 {
1253         struct cam_periph *periph;
1254
1255         periph = (struct cam_periph *)dp->d_drv1;
1256
1257         cam_periph_release(periph);
1258 }
1259
1260 static void
1261 daoninvalidate(struct cam_periph *periph)
1262 {
1263         struct da_softc *softc;
1264
1265         softc = (struct da_softc *)periph->softc;
1266
1267         /*
1268          * De-register any async callbacks.
1269          */
1270         xpt_register_async(0, daasync, periph, periph->path);
1271
1272         softc->flags |= DA_FLAG_PACK_INVALID;
1273
1274         /*
1275          * Return all queued I/O with ENXIO.
1276          * XXX Handle any transactions queued to the card
1277          *     with XPT_ABORT_CCB.
1278          */
1279         bioq_flush(&softc->bio_queue, NULL, ENXIO);
1280         bioq_flush(&softc->delete_queue, NULL, ENXIO);
1281
1282         /*
1283          * Tell GEOM that we've gone away, we'll get a callback when it is
1284          * done cleaning up its resources.
1285          */
1286         disk_gone(softc->disk);
1287
1288         xpt_print(periph->path, "lost device - %d outstanding, %d refs\n",
1289                   softc->outstanding_cmds, periph->refcount);
1290 }
1291
1292 static void
1293 dacleanup(struct cam_periph *periph)
1294 {
1295         struct da_softc *softc;
1296
1297         softc = (struct da_softc *)periph->softc;
1298
1299         xpt_print(periph->path, "removing device entry\n");
1300         cam_periph_unlock(periph);
1301
1302         /*
1303          * If we can't free the sysctl tree, oh well...
1304          */
1305         if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
1306             && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
1307                 xpt_print(periph->path, "can't remove sysctl context\n");
1308         }
1309
1310         disk_destroy(softc->disk);
1311         callout_drain(&softc->sendordered_c);
1312         free(softc, M_DEVBUF);
1313         cam_periph_lock(periph);
1314 }
1315
1316 static void
1317 daasync(void *callback_arg, u_int32_t code,
1318         struct cam_path *path, void *arg)
1319 {
1320         struct cam_periph *periph;
1321
1322         periph = (struct cam_periph *)callback_arg;
1323         switch (code) {
1324         case AC_FOUND_DEVICE:
1325         {
1326                 struct ccb_getdev *cgd;
1327                 cam_status status;
1328  
1329                 cgd = (struct ccb_getdev *)arg;
1330                 if (cgd == NULL)
1331                         break;
1332
1333                 if (cgd->protocol != PROTO_SCSI)
1334                         break;
1335
1336                 if (SID_TYPE(&cgd->inq_data) != T_DIRECT
1337                     && SID_TYPE(&cgd->inq_data) != T_RBC
1338                     && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
1339                         break;
1340
1341                 /*
1342                  * Allocate a peripheral instance for
1343                  * this device and start the probe
1344                  * process.
1345                  */
1346                 status = cam_periph_alloc(daregister, daoninvalidate,
1347                                           dacleanup, dastart,
1348                                           "da", CAM_PERIPH_BIO,
1349                                           cgd->ccb_h.path, daasync,
1350                                           AC_FOUND_DEVICE, cgd);
1351
1352                 if (status != CAM_REQ_CMP
1353                  && status != CAM_REQ_INPROG)
1354                         printf("daasync: Unable to attach to new device "
1355                                 "due to status 0x%x\n", status);
1356                 return;
1357         }
1358         case AC_ADVINFO_CHANGED:
1359         {
1360                 uintptr_t buftype;
1361
1362                 buftype = (uintptr_t)arg;
1363                 if (buftype == CDAI_TYPE_PHYS_PATH) {
1364                         struct da_softc *softc;
1365
1366                         softc = periph->softc;
1367                         disk_attr_changed(softc->disk, "GEOM::physpath",
1368                                           M_NOWAIT);
1369                 }
1370                 break;
1371         }
1372         case AC_SENT_BDR:
1373         case AC_BUS_RESET:
1374         {
1375                 struct da_softc *softc;
1376                 struct ccb_hdr *ccbh;
1377
1378                 softc = (struct da_softc *)periph->softc;
1379                 /*
1380                  * Don't fail on the expected unit attention
1381                  * that will occur.
1382                  */
1383                 softc->flags |= DA_FLAG_RETRY_UA;
1384                 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
1385                         ccbh->ccb_state |= DA_CCB_RETRY_UA;
1386                 break;
1387         }
1388         default:
1389                 break;
1390         }
1391         cam_periph_async(periph, code, path, arg);
1392 }
1393
1394 static void
1395 dasysctlinit(void *context, int pending)
1396 {
1397         struct cam_periph *periph;
1398         struct da_softc *softc;
1399         char tmpstr[80], tmpstr2[80];
1400         struct ccb_trans_settings cts;
1401
1402         periph = (struct cam_periph *)context;
1403         /*
1404          * periph was held for us when this task was enqueued
1405          */
1406         if (periph->flags & CAM_PERIPH_INVALID) {
1407                 cam_periph_release(periph);
1408                 return;
1409         }
1410
1411         softc = (struct da_softc *)periph->softc;
1412         snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
1413         snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
1414
1415         sysctl_ctx_init(&softc->sysctl_ctx);
1416         softc->flags |= DA_FLAG_SCTX_INIT;
1417         softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
1418                 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
1419                 CTLFLAG_RD, 0, tmpstr);
1420         if (softc->sysctl_tree == NULL) {
1421                 printf("dasysctlinit: unable to allocate sysctl tree\n");
1422                 cam_periph_release(periph);
1423                 return;
1424         }
1425
1426         /*
1427          * Now register the sysctl handler, so the user can change the value on
1428          * the fly.
1429          */
1430         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1431                 OID_AUTO, "delete_method", CTLTYPE_STRING | CTLFLAG_RW,
1432                 &softc->delete_method, 0, dadeletemethodsysctl, "A",
1433                 "BIO_DELETE execution method");
1434         SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1435                 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
1436                 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
1437                 "Minimum CDB size");
1438
1439         SYSCTL_ADD_INT(&softc->sysctl_ctx,
1440                        SYSCTL_CHILDREN(softc->sysctl_tree),
1441                        OID_AUTO,
1442                        "error_inject",
1443                        CTLFLAG_RW,
1444                        &softc->error_inject,
1445                        0,
1446                        "error_inject leaf");
1447
1448
1449         /*
1450          * Add some addressing info.
1451          */
1452         memset(&cts, 0, sizeof (cts));
1453         xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
1454         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
1455         cts.type = CTS_TYPE_CURRENT_SETTINGS;
1456         cam_periph_lock(periph);
1457         xpt_action((union ccb *)&cts);
1458         cam_periph_unlock(periph);
1459         if (cts.ccb_h.status != CAM_REQ_CMP) {
1460                 cam_periph_release(periph);
1461                 return;
1462         }
1463         if (cts.protocol == PROTO_SCSI && cts.transport == XPORT_FC) {
1464                 struct ccb_trans_settings_fc *fc = &cts.xport_specific.fc;
1465                 if (fc->valid & CTS_FC_VALID_WWPN) {
1466                         softc->wwpn = fc->wwpn;
1467                         SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1468                             SYSCTL_CHILDREN(softc->sysctl_tree),
1469                             OID_AUTO, "wwpn", CTLFLAG_RD,
1470                             &softc->wwpn, "World Wide Port Name");
1471                 }
1472         }
1473         cam_periph_release(periph);
1474 }
1475
1476 static int
1477 dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
1478 {
1479         int error, value;
1480
1481         value = *(int *)arg1;
1482
1483         error = sysctl_handle_int(oidp, &value, 0, req);
1484
1485         if ((error != 0)
1486          || (req->newptr == NULL))
1487                 return (error);
1488
1489         /*
1490          * Acceptable values here are 6, 10, 12 or 16.
1491          */
1492         if (value < 6)
1493                 value = 6;
1494         else if ((value > 6)
1495               && (value <= 10))
1496                 value = 10;
1497         else if ((value > 10)
1498               && (value <= 12))
1499                 value = 12;
1500         else if (value > 12)
1501                 value = 16;
1502
1503         *(int *)arg1 = value;
1504
1505         return (0);
1506 }
1507
1508 static int
1509 dadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
1510 {
1511         char buf[16];
1512         int error;
1513         const char *p;
1514         int i, value;
1515
1516         value = *(int *)arg1;
1517         if (value < 0 || value > DA_DELETE_MAX)
1518                 p = "UNKNOWN";
1519         else
1520                 p = da_delete_method_names[value];
1521         strncpy(buf, p, sizeof(buf));
1522         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
1523         if (error != 0 || req->newptr == NULL)
1524                 return (error);
1525         for (i = 0; i <= DA_DELETE_MAX; i++) {
1526                 if (strcmp(buf, da_delete_method_names[i]) != 0)
1527                         continue;
1528                 *(int *)arg1 = i;
1529                 return (0);
1530         }
1531         return (EINVAL);
1532 }
1533
1534 static cam_status
1535 daregister(struct cam_periph *periph, void *arg)
1536 {
1537         struct da_softc *softc;
1538         struct ccb_pathinq cpi;
1539         struct ccb_getdev *cgd;
1540         char tmpstr[80];
1541         caddr_t match;
1542
1543         cgd = (struct ccb_getdev *)arg;
1544         if (periph == NULL) {
1545                 printf("daregister: periph was NULL!!\n");
1546                 return(CAM_REQ_CMP_ERR);
1547         }
1548
1549         if (cgd == NULL) {
1550                 printf("daregister: no getdev CCB, can't register device\n");
1551                 return(CAM_REQ_CMP_ERR);
1552         }
1553
1554         softc = (struct da_softc *)malloc(sizeof(*softc), M_DEVBUF,
1555             M_NOWAIT|M_ZERO);
1556
1557         if (softc == NULL) {
1558                 printf("daregister: Unable to probe new device. "
1559                        "Unable to allocate softc\n");                           
1560                 return(CAM_REQ_CMP_ERR);
1561         }
1562
1563         LIST_INIT(&softc->pending_ccbs);
1564         softc->state = DA_STATE_PROBE;
1565         bioq_init(&softc->bio_queue);
1566         bioq_init(&softc->delete_queue);
1567         bioq_init(&softc->delete_run_queue);
1568         if (SID_IS_REMOVABLE(&cgd->inq_data))
1569                 softc->flags |= DA_FLAG_PACK_REMOVABLE;
1570         softc->unmap_max_ranges = UNMAP_MAX_RANGES;
1571         softc->unmap_max_lba = 1024*1024*2;
1572
1573         periph->softc = softc;
1574
1575         /*
1576          * See if this device has any quirks.
1577          */
1578         match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1579                                (caddr_t)da_quirk_table,
1580                                sizeof(da_quirk_table)/sizeof(*da_quirk_table),
1581                                sizeof(*da_quirk_table), scsi_inquiry_match);
1582
1583         if (match != NULL)
1584                 softc->quirks = ((struct da_quirk_entry *)match)->quirks;
1585         else
1586                 softc->quirks = DA_Q_NONE;
1587
1588         /* Check if the SIM does not want 6 byte commands */
1589         bzero(&cpi, sizeof(cpi));
1590         xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1591         cpi.ccb_h.func_code = XPT_PATH_INQ;
1592         xpt_action((union ccb *)&cpi);
1593         if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
1594                 softc->quirks |= DA_Q_NO_6_BYTE;
1595
1596         TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
1597
1598         /*
1599          * Take an exclusive refcount on the periph while dastart is called
1600          * to finish the probe.  The reference will be dropped in dadone at
1601          * the end of probe.
1602          */
1603         (void)cam_periph_hold(periph, PRIBIO);
1604
1605         /*
1606          * Schedule a periodic event to occasionally send an
1607          * ordered tag to a device.
1608          */
1609         callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
1610         callout_reset(&softc->sendordered_c,
1611             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
1612             dasendorderedtag, softc);
1613
1614         mtx_unlock(periph->sim->mtx);
1615         /*
1616          * RBC devices don't have to support READ(6), only READ(10).
1617          */
1618         if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
1619                 softc->minimum_cmd_size = 10;
1620         else
1621                 softc->minimum_cmd_size = 6;
1622
1623         /*
1624          * Load the user's default, if any.
1625          */
1626         snprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
1627                  periph->unit_number);
1628         TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
1629
1630         /*
1631          * 6, 10, 12 and 16 are the currently permissible values.
1632          */
1633         if (softc->minimum_cmd_size < 6)
1634                 softc->minimum_cmd_size = 6;
1635         else if ((softc->minimum_cmd_size > 6)
1636               && (softc->minimum_cmd_size <= 10))
1637                 softc->minimum_cmd_size = 10;
1638         else if ((softc->minimum_cmd_size > 10)
1639               && (softc->minimum_cmd_size <= 12))
1640                 softc->minimum_cmd_size = 12;
1641         else if (softc->minimum_cmd_size > 12)
1642                 softc->minimum_cmd_size = 16;
1643
1644         /* Predict whether device may support READ CAPACITY(16). */
1645         if (SID_ANSI_REV(&cgd->inq_data) >= SCSI_REV_SPC3) {
1646                 softc->flags |= DA_FLAG_CAN_RC16;
1647                 softc->state = DA_STATE_PROBE2;
1648         }
1649
1650         /*
1651          * Register this media as a disk.
1652          */
1653         softc->disk = disk_alloc();
1654         softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
1655                           periph->unit_number, 0,
1656                           DEVSTAT_BS_UNAVAILABLE,
1657                           SID_TYPE(&cgd->inq_data) |
1658                           XPORT_DEVSTAT_TYPE(cpi.transport),
1659                           DEVSTAT_PRIORITY_DISK);
1660         softc->disk->d_open = daopen;
1661         softc->disk->d_close = daclose;
1662         softc->disk->d_strategy = dastrategy;
1663         softc->disk->d_dump = dadump;
1664         softc->disk->d_getattr = dagetattr;
1665         softc->disk->d_gone = dadiskgonecb;
1666         softc->disk->d_name = "da";
1667         softc->disk->d_drv1 = periph;
1668         if (cpi.maxio == 0)
1669                 softc->disk->d_maxsize = DFLTPHYS;      /* traditional default */
1670         else if (cpi.maxio > MAXPHYS)
1671                 softc->disk->d_maxsize = MAXPHYS;       /* for safety */
1672         else
1673                 softc->disk->d_maxsize = cpi.maxio;
1674         softc->disk->d_unit = periph->unit_number;
1675         softc->disk->d_flags = 0;
1676         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0)
1677                 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
1678         cam_strvis(softc->disk->d_descr, cgd->inq_data.vendor,
1679             sizeof(cgd->inq_data.vendor), sizeof(softc->disk->d_descr));
1680         strlcat(softc->disk->d_descr, " ", sizeof(softc->disk->d_descr));
1681         cam_strvis(&softc->disk->d_descr[strlen(softc->disk->d_descr)],
1682             cgd->inq_data.product, sizeof(cgd->inq_data.product),
1683             sizeof(softc->disk->d_descr) - strlen(softc->disk->d_descr));
1684         softc->disk->d_hba_vendor = cpi.hba_vendor;
1685         softc->disk->d_hba_device = cpi.hba_device;
1686         softc->disk->d_hba_subvendor = cpi.hba_subvendor;
1687         softc->disk->d_hba_subdevice = cpi.hba_subdevice;
1688
1689         /*
1690          * Acquire a reference to the periph before we register with GEOM.
1691          * We'll release this reference once GEOM calls us back (via
1692          * dadiskgonecb()) telling us that our provider has been freed.
1693          */
1694         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
1695                 xpt_print(periph->path, "%s: lost periph during "
1696                           "registration!\n", __func__);
1697                 mtx_lock(periph->sim->mtx);
1698                 return (CAM_REQ_CMP_ERR);
1699         }
1700
1701         disk_create(softc->disk, DISK_VERSION);
1702         mtx_lock(periph->sim->mtx);
1703
1704         /*
1705          * Add async callbacks for events of interest.
1706          * I don't bother checking if this fails as,
1707          * in most cases, the system will function just
1708          * fine without them and the only alternative
1709          * would be to not attach the device on failure.
1710          */
1711         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET
1712                          | AC_LOST_DEVICE | AC_ADVINFO_CHANGED,
1713                            daasync, periph, periph->path);
1714
1715         /*
1716          * Emit an attribute changed notification just in case 
1717          * physical path information arrived before our async
1718          * event handler was registered, but after anyone attaching
1719          * to our disk device polled it.
1720          */
1721         disk_attr_changed(softc->disk, "GEOM::physpath", M_NOWAIT);
1722
1723         xpt_schedule(periph, CAM_PRIORITY_DEV);
1724
1725         return(CAM_REQ_CMP);
1726 }
1727
1728 static void
1729 dastart(struct cam_periph *periph, union ccb *start_ccb)
1730 {
1731         struct da_softc *softc;
1732
1733         softc = (struct da_softc *)periph->softc;
1734
1735         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dastart\n"));
1736
1737         switch (softc->state) {
1738         case DA_STATE_NORMAL:
1739         {
1740                 struct bio *bp, *bp1;
1741                 uint8_t tag_code;
1742
1743                 /* Execute immediate CCB if waiting. */
1744                 if (periph->immediate_priority <= periph->pinfo.priority) {
1745                         CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
1746                                         ("queuing for immediate ccb\n"));
1747                         start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
1748                         SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1749                                           periph_links.sle);
1750                         periph->immediate_priority = CAM_PRIORITY_NONE;
1751                         wakeup(&periph->ccb_list);
1752                         /* May have more work to do, so ensure we stay scheduled */
1753                         daschedule(periph);
1754                         break;
1755                 }
1756
1757                 /* Run BIO_DELETE if not running yet. */
1758                 if (!softc->delete_running &&
1759                     (bp = bioq_first(&softc->delete_queue)) != NULL) {
1760                     uint64_t lba;
1761                     u_int count;
1762
1763                     if (softc->delete_method == DA_DELETE_UNMAP) {
1764                         uint8_t *buf = softc->unmap_buf;
1765                         uint64_t lastlba = (uint64_t)-1;
1766                         uint32_t lastcount = 0;
1767                         int blocks = 0, off, ranges = 0;
1768
1769                         softc->delete_running = 1;
1770                         bzero(softc->unmap_buf, sizeof(softc->unmap_buf));
1771                         bp1 = bp;
1772                         do {
1773                                 bioq_remove(&softc->delete_queue, bp1);
1774                                 if (bp1 != bp)
1775                                         bioq_insert_tail(&softc->delete_run_queue, bp1);
1776                                 lba = bp1->bio_pblkno;
1777                                 count = bp1->bio_bcount / softc->params.secsize;
1778
1779                                 /* Try to extend the previous range. */
1780                                 if (lba == lastlba) {
1781                                         lastcount += count;
1782                                         off = (ranges - 1) * 16 + 8;
1783                                         scsi_ulto4b(lastcount, &buf[off + 8]);
1784                                 } else if (count > 0) {
1785                                         off = ranges * 16 + 8;
1786                                         scsi_u64to8b(lba, &buf[off + 0]);
1787                                         scsi_ulto4b(count, &buf[off + 8]);
1788                                         lastcount = count;
1789                                         ranges++;
1790                                 }
1791                                 blocks += count;
1792                                 lastlba = lba + count;
1793                                 bp1 = bioq_first(&softc->delete_queue);
1794                                 if (bp1 == NULL ||
1795                                     ranges >= softc->unmap_max_ranges ||
1796                                     blocks + bp1->bio_bcount /
1797                                      softc->params.secsize > softc->unmap_max_lba)
1798                                         break;
1799                         } while (1);
1800                         scsi_ulto2b(ranges * 16 + 6, &buf[0]);
1801                         scsi_ulto2b(ranges * 16, &buf[2]);
1802
1803                         scsi_unmap(&start_ccb->csio,
1804                                         /*retries*/da_retry_count,
1805                                         /*cbfcnp*/dadone,
1806                                         /*tag_action*/MSG_SIMPLE_Q_TAG,
1807                                         /*byte2*/0,
1808                                         /*data_ptr*/ buf,
1809                                         /*dxfer_len*/ ranges * 16 + 8,
1810                                         /*sense_len*/SSD_FULL_SIZE,
1811                                         da_default_timeout * 1000);
1812                         start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
1813                         goto out;
1814                     } else if (softc->delete_method == DA_DELETE_ZERO ||
1815                                softc->delete_method == DA_DELETE_WS10 ||
1816                                softc->delete_method == DA_DELETE_WS16) {
1817                         softc->delete_running = 1;
1818                         lba = bp->bio_pblkno;
1819                         count = 0;
1820                         bp1 = bp;
1821                         do {
1822                                 bioq_remove(&softc->delete_queue, bp1);
1823                                 if (bp1 != bp)
1824                                         bioq_insert_tail(&softc->delete_run_queue, bp1);
1825                                 count += bp1->bio_bcount / softc->params.secsize;
1826                                 bp1 = bioq_first(&softc->delete_queue);
1827                                 if (bp1 == NULL ||
1828                                     lba + count != bp1->bio_pblkno ||
1829                                     count + bp1->bio_bcount /
1830                                      softc->params.secsize > 0xffff)
1831                                         break;
1832                         } while (1);
1833
1834                         scsi_write_same(&start_ccb->csio,
1835                                         /*retries*/da_retry_count,
1836                                         /*cbfcnp*/dadone,
1837                                         /*tag_action*/MSG_SIMPLE_Q_TAG,
1838                                         /*byte2*/softc->delete_method ==
1839                                             DA_DELETE_ZERO ? 0 : SWS_UNMAP,
1840                                         softc->delete_method ==
1841                                             DA_DELETE_WS16 ? 16 : 10,
1842                                         /*lba*/lba,
1843                                         /*block_count*/count,
1844                                         /*data_ptr*/ __DECONST(void *,
1845                                             zero_region),
1846                                         /*dxfer_len*/ softc->params.secsize,
1847                                         /*sense_len*/SSD_FULL_SIZE,
1848                                         da_default_timeout * 1000);
1849                         start_ccb->ccb_h.ccb_state = DA_CCB_DELETE;
1850                         goto out;
1851                     } else {
1852                         bioq_flush(&softc->delete_queue, NULL, 0);
1853                         /* FALLTHROUGH */
1854                     }
1855                 }
1856
1857                 /* Run regular command. */
1858                 bp = bioq_takefirst(&softc->bio_queue);
1859                 if (bp == NULL) {
1860                         xpt_release_ccb(start_ccb);
1861                         break;
1862                 }
1863
1864                 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
1865                     (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
1866                         softc->flags &= ~DA_FLAG_NEED_OTAG;
1867                         softc->ordered_tag_count++;
1868                         tag_code = MSG_ORDERED_Q_TAG;
1869                 } else {
1870                         tag_code = MSG_SIMPLE_Q_TAG;
1871                 }
1872
1873                 switch (bp->bio_cmd) {
1874                 case BIO_READ:
1875                 case BIO_WRITE:
1876                         scsi_read_write(&start_ccb->csio,
1877                                         /*retries*/da_retry_count,
1878                                         /*cbfcnp*/dadone,
1879                                         /*tag_action*/tag_code,
1880                                         /*read_op*/bp->bio_cmd
1881                                                 == BIO_READ,
1882                                         /*byte2*/0,
1883                                         softc->minimum_cmd_size,
1884                                         /*lba*/bp->bio_pblkno,
1885                                         /*block_count*/bp->bio_bcount /
1886                                         softc->params.secsize,
1887                                         /*data_ptr*/ bp->bio_data,
1888                                         /*dxfer_len*/ bp->bio_bcount,
1889                                         /*sense_len*/SSD_FULL_SIZE,
1890                                         da_default_timeout * 1000);
1891                         break;
1892                 case BIO_FLUSH:
1893                         /*
1894                          * BIO_FLUSH doesn't currently communicate
1895                          * range data, so we synchronize the cache
1896                          * over the whole disk.  We also force
1897                          * ordered tag semantics the flush applies
1898                          * to all previously queued I/O.
1899                          */
1900                         scsi_synchronize_cache(&start_ccb->csio,
1901                                                /*retries*/1,
1902                                                /*cbfcnp*/dadone,
1903                                                MSG_ORDERED_Q_TAG,
1904                                                /*begin_lba*/0,
1905                                                /*lb_count*/0,
1906                                                SSD_FULL_SIZE,
1907                                                da_default_timeout*1000);
1908                         break;
1909                 }
1910                 start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
1911
1912 out:
1913                 /*
1914                  * Block out any asyncronous callbacks
1915                  * while we touch the pending ccb list.
1916                  */
1917                 LIST_INSERT_HEAD(&softc->pending_ccbs,
1918                                  &start_ccb->ccb_h, periph_links.le);
1919                 softc->outstanding_cmds++;
1920
1921                 /* We expect a unit attention from this device */
1922                 if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
1923                         start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
1924                         softc->flags &= ~DA_FLAG_RETRY_UA;
1925                 }
1926
1927                 start_ccb->ccb_h.ccb_bp = bp;
1928                 xpt_action(start_ccb);
1929
1930                 /* May have more work to do, so ensure we stay scheduled */
1931                 daschedule(periph);
1932                 break;
1933         }
1934         case DA_STATE_PROBE:
1935         {
1936                 struct ccb_scsiio *csio;
1937                 struct scsi_read_capacity_data *rcap;
1938
1939                 rcap = (struct scsi_read_capacity_data *)
1940                     malloc(sizeof(*rcap), M_SCSIDA, M_NOWAIT|M_ZERO);
1941                 if (rcap == NULL) {
1942                         printf("dastart: Couldn't malloc read_capacity data\n");
1943                         /* da_free_periph??? */
1944                         break;
1945                 }
1946                 csio = &start_ccb->csio;
1947                 scsi_read_capacity(csio,
1948                                    /*retries*/4,
1949                                    dadone,
1950                                    MSG_SIMPLE_Q_TAG,
1951                                    rcap,
1952                                    SSD_FULL_SIZE,
1953                                    /*timeout*/5000);
1954                 start_ccb->ccb_h.ccb_bp = NULL;
1955                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE;
1956                 xpt_action(start_ccb);
1957                 break;
1958         }
1959         case DA_STATE_PROBE2:
1960         {
1961                 struct ccb_scsiio *csio;
1962                 struct scsi_read_capacity_data_long *rcaplong;
1963
1964                 rcaplong = (struct scsi_read_capacity_data_long *)
1965                         malloc(sizeof(*rcaplong), M_SCSIDA, M_NOWAIT|M_ZERO);
1966                 if (rcaplong == NULL) {
1967                         printf("dastart: Couldn't malloc read_capacity data\n");
1968                         /* da_free_periph??? */
1969                         break;
1970                 }
1971                 csio = &start_ccb->csio;
1972                 scsi_read_capacity_16(csio,
1973                                       /*retries*/ 4,
1974                                       /*cbfcnp*/ dadone,
1975                                       /*tag_action*/ MSG_SIMPLE_Q_TAG,
1976                                       /*lba*/ 0,
1977                                       /*reladr*/ 0,
1978                                       /*pmi*/ 0,
1979                                       rcaplong,
1980                                       /*sense_len*/ SSD_FULL_SIZE,
1981                                       /*timeout*/ 60000);
1982                 start_ccb->ccb_h.ccb_bp = NULL;
1983                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE2;
1984                 xpt_action(start_ccb);  
1985                 break;
1986         }
1987         }
1988 }
1989
1990 static int
1991 cmd6workaround(union ccb *ccb)
1992 {
1993         struct scsi_rw_6 cmd6;
1994         struct scsi_rw_10 *cmd10;
1995         struct da_softc *softc;
1996         u_int8_t *cdb;
1997         struct bio *bp;
1998         int frozen;
1999
2000         cdb = ccb->csio.cdb_io.cdb_bytes;
2001         softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
2002
2003         if (ccb->ccb_h.ccb_state == DA_CCB_DELETE) {
2004                 if (softc->delete_method == DA_DELETE_UNMAP) {
2005                         xpt_print(ccb->ccb_h.path, "UNMAP is not supported, "
2006                             "switching to WRITE SAME(16) with UNMAP.\n");
2007                         softc->delete_method = DA_DELETE_WS16;
2008                 } else if (softc->delete_method == DA_DELETE_WS16) {
2009                         xpt_print(ccb->ccb_h.path,
2010                             "WRITE SAME(16) with UNMAP is not supported, "
2011                             "disabling BIO_DELETE.\n");
2012                         softc->delete_method = DA_DELETE_DISABLE;
2013                 } else if (softc->delete_method == DA_DELETE_WS10) {
2014                         xpt_print(ccb->ccb_h.path,
2015                             "WRITE SAME(10) with UNMAP is not supported, "
2016                             "disabling BIO_DELETE.\n");
2017                         softc->delete_method = DA_DELETE_DISABLE;
2018                 } else if (softc->delete_method == DA_DELETE_ZERO) {
2019                         xpt_print(ccb->ccb_h.path,
2020                             "WRITE SAME(10) is not supported, "
2021                             "disabling BIO_DELETE.\n");
2022                         softc->delete_method = DA_DELETE_DISABLE;
2023                 } else
2024                         softc->delete_method = DA_DELETE_DISABLE;
2025                 while ((bp = bioq_takefirst(&softc->delete_run_queue))
2026                     != NULL)
2027                         bioq_disksort(&softc->delete_queue, bp);
2028                 bioq_insert_tail(&softc->delete_queue,
2029                     (struct bio *)ccb->ccb_h.ccb_bp);
2030                 ccb->ccb_h.ccb_bp = NULL;
2031                 return (0);
2032         }
2033
2034         /* Translation only possible if CDB is an array and cmd is R/W6 */
2035         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
2036             (*cdb != READ_6 && *cdb != WRITE_6))
2037                 return 0;
2038
2039         xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
2040             "increasing minimum_cmd_size to 10.\n");
2041         softc->minimum_cmd_size = 10;
2042
2043         bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
2044         cmd10 = (struct scsi_rw_10 *)cdb;
2045         cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
2046         cmd10->byte2 = 0;
2047         scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
2048         cmd10->reserved = 0;
2049         scsi_ulto2b(cmd6.length, cmd10->length);
2050         cmd10->control = cmd6.control;
2051         ccb->csio.cdb_len = sizeof(*cmd10);
2052
2053         /* Requeue request, unfreezing queue if necessary */
2054         frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
2055         ccb->ccb_h.status = CAM_REQUEUE_REQ;
2056         xpt_action(ccb);
2057         if (frozen) {
2058                 cam_release_devq(ccb->ccb_h.path,
2059                                  /*relsim_flags*/0,
2060                                  /*reduction*/0,
2061                                  /*timeout*/0,
2062                                  /*getcount_only*/0);
2063         }
2064         return (ERESTART);
2065 }
2066
2067 static void
2068 dadone(struct cam_periph *periph, union ccb *done_ccb)
2069 {
2070         struct da_softc *softc;
2071         struct ccb_scsiio *csio;
2072         u_int32_t  priority;
2073
2074         softc = (struct da_softc *)periph->softc;
2075         priority = done_ccb->ccb_h.pinfo.priority;
2076
2077         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("dadone\n"));
2078
2079         csio = &done_ccb->csio;
2080         switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
2081         case DA_CCB_BUFFER_IO:
2082         case DA_CCB_DELETE:
2083         {
2084                 struct bio *bp, *bp1;
2085
2086                 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2087                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2088                         int error;
2089                         int sf;
2090
2091                         if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
2092                                 sf = SF_RETRY_UA;
2093                         else
2094                                 sf = 0;
2095
2096                         error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
2097                         if (error == ERESTART) {
2098                                 /*
2099                                  * A retry was scheuled, so
2100                                  * just return.
2101                                  */
2102                                 return;
2103                         }
2104                         bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2105                         if (error != 0) {
2106                                 int queued_error;
2107
2108                                 /*
2109                                  * return all queued I/O with EIO, so that
2110                                  * the client can retry these I/Os in the
2111                                  * proper order should it attempt to recover.
2112                                  */
2113                                 queued_error = EIO;
2114
2115                                 if (error == ENXIO
2116                                  && (softc->flags & DA_FLAG_PACK_INVALID)== 0) {
2117                                         /*
2118                                          * Catastrophic error.  Mark our pack as
2119                                          * invalid.
2120                                          */
2121                                         /*
2122                                          * XXX See if this is really a media
2123                                          * XXX change first?
2124                                          */
2125                                         xpt_print(periph->path,
2126                                             "Invalidating pack\n");
2127                                         softc->flags |= DA_FLAG_PACK_INVALID;
2128                                         queued_error = ENXIO;
2129                                 }
2130                                 bioq_flush(&softc->bio_queue, NULL,
2131                                            queued_error);
2132                                 if (bp != NULL) {
2133                                         bp->bio_error = error;
2134                                         bp->bio_resid = bp->bio_bcount;
2135                                         bp->bio_flags |= BIO_ERROR;
2136                                 }
2137                         } else if (bp != NULL) {
2138                                 bp->bio_resid = csio->resid;
2139                                 bp->bio_error = 0;
2140                                 if (bp->bio_resid != 0)
2141                                         bp->bio_flags |= BIO_ERROR;
2142                         }
2143                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2144                                 cam_release_devq(done_ccb->ccb_h.path,
2145                                                  /*relsim_flags*/0,
2146                                                  /*reduction*/0,
2147                                                  /*timeout*/0,
2148                                                  /*getcount_only*/0);
2149                 } else if (bp != NULL) {
2150                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2151                                 panic("REQ_CMP with QFRZN");
2152                         bp->bio_resid = csio->resid;
2153                         if (csio->resid > 0)
2154                                 bp->bio_flags |= BIO_ERROR;
2155                         if (softc->error_inject != 0) {
2156                                 bp->bio_error = softc->error_inject;
2157                                 bp->bio_resid = bp->bio_bcount;
2158                                 bp->bio_flags |= BIO_ERROR;
2159                                 softc->error_inject = 0;
2160                         }
2161
2162                 }
2163
2164                 /*
2165                  * Block out any asyncronous callbacks
2166                  * while we touch the pending ccb list.
2167                  */
2168                 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
2169                 softc->outstanding_cmds--;
2170                 if (softc->outstanding_cmds == 0)
2171                         softc->flags |= DA_FLAG_WENT_IDLE;
2172
2173                 if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
2174                         xpt_print(periph->path, "oustanding %d\n",
2175                                   softc->outstanding_cmds);
2176                 }
2177
2178                 if ((csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) ==
2179                     DA_CCB_DELETE) {
2180                         while ((bp1 = bioq_takefirst(&softc->delete_run_queue))
2181                             != NULL) {
2182                                 bp1->bio_resid = bp->bio_resid;
2183                                 bp1->bio_error = bp->bio_error;
2184                                 if (bp->bio_flags & BIO_ERROR)
2185                                         bp1->bio_flags |= BIO_ERROR;
2186                                 biodone(bp1);
2187                         }
2188                         softc->delete_running = 0;
2189                         if (bp != NULL)
2190                                 biodone(bp);
2191                         daschedule(periph);
2192                 } else if (bp != NULL)
2193                         biodone(bp);
2194                 break;
2195         }
2196         case DA_CCB_PROBE:
2197         case DA_CCB_PROBE2:
2198         {
2199                 struct     scsi_read_capacity_data *rdcap;
2200                 struct     scsi_read_capacity_data_long *rcaplong;
2201                 char       announce_buf[80];
2202
2203                 rdcap = NULL;
2204                 rcaplong = NULL;
2205                 if (softc->state == DA_STATE_PROBE)
2206                         rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
2207                 else
2208                         rcaplong = (struct scsi_read_capacity_data_long *)
2209                                 csio->data_ptr;
2210
2211                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
2212                         struct disk_params *dp;
2213                         uint32_t block_size;
2214                         uint64_t maxsector;
2215                         u_int lbppbe;   /* LB per physical block exponent. */
2216                         u_int lalba;    /* Lowest aligned LBA. */
2217
2218                         if (softc->state == DA_STATE_PROBE) {
2219                                 block_size = scsi_4btoul(rdcap->length);
2220                                 maxsector = scsi_4btoul(rdcap->addr);
2221                                 lbppbe = 0;
2222                                 lalba = 0;
2223
2224                                 /*
2225                                  * According to SBC-2, if the standard 10
2226                                  * byte READ CAPACITY command returns 2^32,
2227                                  * we should issue the 16 byte version of
2228                                  * the command, since the device in question
2229                                  * has more sectors than can be represented
2230                                  * with the short version of the command.
2231                                  */
2232                                 if (maxsector == 0xffffffff) {
2233                                         softc->state = DA_STATE_PROBE2;
2234                                         free(rdcap, M_SCSIDA);
2235                                         xpt_release_ccb(done_ccb);
2236                                         xpt_schedule(periph, priority);
2237                                         return;
2238                                 }
2239                         } else {
2240                                 block_size = scsi_4btoul(rcaplong->length);
2241                                 maxsector = scsi_8btou64(rcaplong->addr);
2242                                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
2243                                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
2244                         }
2245
2246                         /*
2247                          * Because GEOM code just will panic us if we
2248                          * give them an 'illegal' value we'll avoid that
2249                          * here.
2250                          */
2251                         if (block_size == 0 && maxsector == 0) {
2252                                 snprintf(announce_buf, sizeof(announce_buf),
2253                                         "0MB (no media?)");
2254                         } else if (block_size >= MAXPHYS || block_size == 0) {
2255                                 xpt_print(periph->path,
2256                                     "unsupportable block size %ju\n",
2257                                     (uintmax_t) block_size);
2258                                 announce_buf[0] = '\0';
2259                                 cam_periph_invalidate(periph);
2260                         } else {
2261                                 dasetgeom(periph, block_size, maxsector,
2262                                     lbppbe, lalba & SRC16_LALBA);
2263                                 if ((lalba & SRC16_LBPME) &&
2264                                     softc->delete_method == DA_DELETE_NONE)
2265                                         softc->delete_method = DA_DELETE_UNMAP;
2266                                 dp = &softc->params;
2267                                 snprintf(announce_buf, sizeof(announce_buf),
2268                                         "%juMB (%ju %u byte sectors: %dH %dS/T "
2269                                         "%dC)", (uintmax_t)
2270                                         (((uintmax_t)dp->secsize *
2271                                         dp->sectors) / (1024*1024)),
2272                                         (uintmax_t)dp->sectors,
2273                                         dp->secsize, dp->heads,
2274                                         dp->secs_per_track, dp->cylinders);
2275                         }
2276                 } else {
2277                         int     error;
2278
2279                         announce_buf[0] = '\0';
2280
2281                         /*
2282                          * Retry any UNIT ATTENTION type errors.  They
2283                          * are expected at boot.
2284                          */
2285                         error = daerror(done_ccb, CAM_RETRY_SELTO,
2286                                         SF_RETRY_UA|SF_NO_PRINT);
2287                         if (error == ERESTART) {
2288                                 /*
2289                                  * A retry was scheuled, so
2290                                  * just return.
2291                                  */
2292                                 return;
2293                         } else if (error != 0) {
2294                                 struct scsi_sense_data *sense;
2295                                 int asc, ascq;
2296                                 int sense_key, error_code;
2297                                 int have_sense;
2298                                 cam_status status;
2299                                 struct ccb_getdev cgd;
2300
2301                                 /* Don't wedge this device's queue */
2302                                 status = done_ccb->ccb_h.status;
2303                                 if ((status & CAM_DEV_QFRZN) != 0)
2304                                         cam_release_devq(done_ccb->ccb_h.path,
2305                                                          /*relsim_flags*/0,
2306                                                          /*reduction*/0,
2307                                                          /*timeout*/0,
2308                                                          /*getcount_only*/0);
2309
2310
2311                                 xpt_setup_ccb(&cgd.ccb_h, 
2312                                               done_ccb->ccb_h.path,
2313                                               CAM_PRIORITY_NORMAL);
2314                                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
2315                                 xpt_action((union ccb *)&cgd);
2316
2317                                 if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
2318                                  || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
2319                                  || ((status & CAM_AUTOSNS_VALID) == 0))
2320                                         have_sense = FALSE;
2321                                 else
2322                                         have_sense = TRUE;
2323
2324                                 if (have_sense) {
2325                                         sense = &csio->sense_data;
2326                                         scsi_extract_sense_len(sense,
2327                                             csio->sense_len - csio->sense_resid,
2328                                             &error_code, &sense_key, &asc,
2329                                             &ascq, /*show_errors*/ 1);
2330                                 }
2331                                 /*
2332                                  * If we tried READ CAPACITY(16) and failed,
2333                                  * fallback to READ CAPACITY(10).
2334                                  */
2335                                 if ((softc->state == DA_STATE_PROBE2) &&
2336                                     (softc->flags & DA_FLAG_CAN_RC16) &&
2337                                     (((csio->ccb_h.status & CAM_STATUS_MASK) ==
2338                                         CAM_REQ_INVALID) ||
2339                                      ((have_sense) &&
2340                                       (error_code == SSD_CURRENT_ERROR) &&
2341                                       (sense_key == SSD_KEY_ILLEGAL_REQUEST)))) {
2342                                         softc->flags &= ~DA_FLAG_CAN_RC16;
2343                                         softc->state = DA_STATE_PROBE;
2344                                         free(rdcap, M_SCSIDA);
2345                                         xpt_release_ccb(done_ccb);
2346                                         xpt_schedule(periph, priority);
2347                                         return;
2348                                 } else
2349                                 /*
2350                                  * Attach to anything that claims to be a
2351                                  * direct access or optical disk device,
2352                                  * as long as it doesn't return a "Logical
2353                                  * unit not supported" (0x25) error.
2354                                  */
2355                                 if ((have_sense) && (asc != 0x25)
2356                                  && (error_code == SSD_CURRENT_ERROR)) {
2357                                         const char *sense_key_desc;
2358                                         const char *asc_desc;
2359
2360                                         scsi_sense_desc(sense_key, asc, ascq,
2361                                                         &cgd.inq_data,
2362                                                         &sense_key_desc,
2363                                                         &asc_desc);
2364                                         snprintf(announce_buf,
2365                                             sizeof(announce_buf),
2366                                                 "Attempt to query device "
2367                                                 "size failed: %s, %s",
2368                                                 sense_key_desc,
2369                                                 asc_desc);
2370                                 } else { 
2371                                         if (have_sense)
2372                                                 scsi_sense_print(
2373                                                         &done_ccb->csio);
2374                                         else {
2375                                                 xpt_print(periph->path,
2376                                                     "got CAM status %#x\n",
2377                                                     done_ccb->ccb_h.status);
2378                                         }
2379
2380                                         xpt_print(periph->path, "fatal error, "
2381                                             "failed to attach to device\n");
2382
2383                                         /*
2384                                          * Free up resources.
2385                                          */
2386                                         cam_periph_invalidate(periph);
2387                                 } 
2388                         }
2389                 }
2390                 free(csio->data_ptr, M_SCSIDA);
2391                 if (announce_buf[0] != '\0') {
2392                         /*
2393                          * Create our sysctl variables, now that we know
2394                          * we have successfully attached.
2395                          */
2396                         /* increase the refcount */
2397                         if (cam_periph_acquire(periph) == CAM_REQ_CMP) {
2398                                 taskqueue_enqueue(taskqueue_thread,
2399                                                   &softc->sysctl_task);
2400                                 xpt_announce_periph(periph, announce_buf);
2401                         } else {
2402                                 xpt_print(periph->path, "fatal error, "
2403                                     "could not acquire reference count\n");
2404                         }
2405                                 
2406                 }
2407                 softc->state = DA_STATE_NORMAL; 
2408                 /*
2409                  * Since our peripheral may be invalidated by an error
2410                  * above or an external event, we must release our CCB
2411                  * before releasing the probe lock on the peripheral.
2412                  * The peripheral will only go away once the last lock
2413                  * is removed, and we need it around for the CCB release
2414                  * operation.
2415                  */
2416                 xpt_release_ccb(done_ccb);
2417                 cam_periph_unhold(periph);
2418                 return;
2419         }
2420         case DA_CCB_WAITING:
2421         {
2422                 /* Caller will release the CCB */
2423                 wakeup(&done_ccb->ccb_h.cbfcnp);
2424                 return;
2425         }
2426         case DA_CCB_DUMP:
2427                 /* No-op.  We're polling */
2428                 return;
2429         default:
2430                 break;
2431         }
2432         xpt_release_ccb(done_ccb);
2433 }
2434
2435 static int
2436 daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
2437 {
2438         struct da_softc   *softc;
2439         struct cam_periph *periph;
2440         int error;
2441
2442         periph = xpt_path_periph(ccb->ccb_h.path);
2443         softc = (struct da_softc *)periph->softc;
2444
2445         /*
2446          * Automatically detect devices that do not support
2447          * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
2448          */
2449         error = 0;
2450         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
2451                 error = cmd6workaround(ccb);
2452         } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
2453                    CAM_SCSI_STATUS_ERROR)
2454          && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
2455          && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
2456          && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
2457          && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
2458                 int sense_key, error_code, asc, ascq;
2459
2460                 scsi_extract_sense(&ccb->csio.sense_data,
2461                                    &error_code, &sense_key, &asc, &ascq);
2462                 if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
2463                         error = cmd6workaround(ccb);
2464         }
2465         if (error == ERESTART)
2466                 return (ERESTART);
2467
2468         /*
2469          * XXX
2470          * Until we have a better way of doing pack validation,
2471          * don't treat UAs as errors.
2472          */
2473         sense_flags |= SF_RETRY_UA;
2474         return(cam_periph_error(ccb, cam_flags, sense_flags,
2475                                 &softc->saved_ccb));
2476 }
2477
2478 static void
2479 daprevent(struct cam_periph *periph, int action)
2480 {
2481         struct  da_softc *softc;
2482         union   ccb *ccb;               
2483         int     error;
2484                 
2485         softc = (struct da_softc *)periph->softc;
2486
2487         if (((action == PR_ALLOW)
2488           && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
2489          || ((action == PR_PREVENT)
2490           && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
2491                 return;
2492         }
2493
2494         ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
2495
2496         scsi_prevent(&ccb->csio,
2497                      /*retries*/1,
2498                      /*cbcfp*/dadone,
2499                      MSG_SIMPLE_Q_TAG,
2500                      action,
2501                      SSD_FULL_SIZE,
2502                      5000);
2503
2504         error = cam_periph_runccb(ccb, daerror, CAM_RETRY_SELTO,
2505             SF_RETRY_UA | SF_QUIET_IR, softc->disk->d_devstat);
2506
2507         if (error == 0) {
2508                 if (action == PR_ALLOW)
2509                         softc->flags &= ~DA_FLAG_PACK_LOCKED;
2510                 else
2511                         softc->flags |= DA_FLAG_PACK_LOCKED;
2512         }
2513
2514         xpt_release_ccb(ccb);
2515 }
2516
2517 static int
2518 dagetcapacity(struct cam_periph *periph)
2519 {
2520         struct da_softc *softc;
2521         union ccb *ccb;
2522         struct scsi_read_capacity_data *rcap;
2523         struct scsi_read_capacity_data_long *rcaplong;
2524         uint32_t block_len;
2525         uint64_t maxsector;
2526         int error, rc16failed;
2527         u_int32_t sense_flags;
2528         u_int lbppbe;   /* Logical blocks per physical block exponent. */
2529         u_int lalba;    /* Lowest aligned LBA. */
2530
2531         softc = (struct da_softc *)periph->softc;
2532         block_len = 0;
2533         maxsector = 0;
2534         lbppbe = 0;
2535         lalba = 0;
2536         error = 0;
2537         rc16failed = 0;
2538         sense_flags = SF_RETRY_UA;
2539         if (softc->flags & DA_FLAG_PACK_REMOVABLE)
2540                 sense_flags |= SF_NO_PRINT;
2541
2542         /* Do a read capacity */
2543         rcap = (struct scsi_read_capacity_data *)malloc(sizeof(*rcaplong),
2544                                                         M_SCSIDA,
2545                                                         M_NOWAIT | M_ZERO);
2546         if (rcap == NULL)
2547                 return (ENOMEM);
2548         rcaplong = (struct scsi_read_capacity_data_long *)rcap;
2549
2550         ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
2551
2552         /* Try READ CAPACITY(16) first if we think it should work. */
2553         if (softc->flags & DA_FLAG_CAN_RC16) {
2554                 scsi_read_capacity_16(&ccb->csio,
2555                               /*retries*/ 4,
2556                               /*cbfcnp*/ dadone,
2557                               /*tag_action*/ MSG_SIMPLE_Q_TAG,
2558                               /*lba*/ 0,
2559                               /*reladr*/ 0,
2560                               /*pmi*/ 0,
2561                               rcaplong,
2562                               /*sense_len*/ SSD_FULL_SIZE,
2563                               /*timeout*/ 60000);
2564                 ccb->ccb_h.ccb_bp = NULL;
2565
2566                 error = cam_periph_runccb(ccb, daerror,
2567                                   /*cam_flags*/CAM_RETRY_SELTO,
2568                                   sense_flags,
2569                                   softc->disk->d_devstat);
2570                 if (error == 0)
2571                         goto rc16ok;
2572
2573                 /* If we got ILLEGAL REQUEST, do not prefer RC16 any more. */
2574                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
2575                      CAM_REQ_INVALID) {
2576                         softc->flags &= ~DA_FLAG_CAN_RC16;
2577                 } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
2578                      CAM_SCSI_STATUS_ERROR) &&
2579                     (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND) &&
2580                     (ccb->ccb_h.status & CAM_AUTOSNS_VALID) &&
2581                     ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0) &&
2582                     ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
2583                         int sense_key, error_code, asc, ascq;
2584
2585                         scsi_extract_sense(&ccb->csio.sense_data,
2586                                    &error_code, &sense_key, &asc, &ascq);
2587                         if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
2588                                 softc->flags &= ~DA_FLAG_CAN_RC16;
2589                 }
2590                 rc16failed = 1;
2591         }
2592
2593         /* Do READ CAPACITY(10). */
2594         scsi_read_capacity(&ccb->csio,
2595                            /*retries*/4,
2596                            /*cbfncp*/dadone,
2597                            MSG_SIMPLE_Q_TAG,
2598                            rcap,
2599                            SSD_FULL_SIZE,
2600                            /*timeout*/60000);
2601         ccb->ccb_h.ccb_bp = NULL;
2602
2603         error = cam_periph_runccb(ccb, daerror,
2604                                   /*cam_flags*/CAM_RETRY_SELTO,
2605                                   sense_flags,
2606                                   softc->disk->d_devstat);
2607         if (error == 0) {
2608                 block_len = scsi_4btoul(rcap->length);
2609                 maxsector = scsi_4btoul(rcap->addr);
2610
2611                 if (maxsector != 0xffffffff || rc16failed)
2612                         goto done;
2613         } else
2614                 goto done;
2615
2616         /* If READ CAPACITY(10) returned overflow, use READ CAPACITY(16) */
2617         scsi_read_capacity_16(&ccb->csio,
2618                               /*retries*/ 4,
2619                               /*cbfcnp*/ dadone,
2620                               /*tag_action*/ MSG_SIMPLE_Q_TAG,
2621                               /*lba*/ 0,
2622                               /*reladr*/ 0,
2623                               /*pmi*/ 0,
2624                               rcaplong,
2625                               /*sense_len*/ SSD_FULL_SIZE,
2626                               /*timeout*/ 60000);
2627         ccb->ccb_h.ccb_bp = NULL;
2628
2629         error = cam_periph_runccb(ccb, daerror,
2630                                   /*cam_flags*/CAM_RETRY_SELTO,
2631                                   sense_flags,
2632                                   softc->disk->d_devstat);
2633         if (error == 0) {
2634 rc16ok:
2635                 block_len = scsi_4btoul(rcaplong->length);
2636                 maxsector = scsi_8btou64(rcaplong->addr);
2637                 lbppbe = rcaplong->prot_lbppbe & SRC16_LBPPBE;
2638                 lalba = scsi_2btoul(rcaplong->lalba_lbp);
2639         }
2640
2641 done:
2642
2643         if (error == 0) {
2644                 if (block_len >= MAXPHYS || block_len == 0) {
2645                         xpt_print(periph->path,
2646                             "unsupportable block size %ju\n",
2647                             (uintmax_t) block_len);
2648                         error = EINVAL;
2649                 } else {
2650                         dasetgeom(periph, block_len, maxsector,
2651                             lbppbe, lalba & SRC16_LALBA);
2652                         if ((lalba & SRC16_LBPME) &&
2653                             softc->delete_method == DA_DELETE_NONE)
2654                                 softc->delete_method = DA_DELETE_UNMAP;
2655                 }
2656         }
2657
2658         xpt_release_ccb(ccb);
2659
2660         free(rcap, M_SCSIDA);
2661
2662         return (error);
2663 }
2664
2665 static void
2666 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector,
2667     u_int lbppbe, u_int lalba)
2668 {
2669         struct ccb_calc_geometry ccg;
2670         struct da_softc *softc;
2671         struct disk_params *dp;
2672
2673         softc = (struct da_softc *)periph->softc;
2674
2675         dp = &softc->params;
2676         dp->secsize = block_len;
2677         dp->sectors = maxsector + 1;
2678         if (lbppbe > 0) {
2679                 dp->stripesize = block_len << lbppbe;
2680                 dp->stripeoffset = (dp->stripesize - block_len * lalba) %
2681                     dp->stripesize;
2682         } else if (softc->quirks & DA_Q_4K) {
2683                 dp->stripesize = 4096;
2684                 dp->stripeoffset = 0;
2685         } else {
2686                 dp->stripesize = 0;
2687                 dp->stripeoffset = 0;
2688         }
2689         /*
2690          * Have the controller provide us with a geometry
2691          * for this disk.  The only time the geometry
2692          * matters is when we boot and the controller
2693          * is the only one knowledgeable enough to come
2694          * up with something that will make this a bootable
2695          * device.
2696          */
2697         xpt_setup_ccb(&ccg.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
2698         ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
2699         ccg.block_size = dp->secsize;
2700         ccg.volume_size = dp->sectors;
2701         ccg.heads = 0;
2702         ccg.secs_per_track = 0;
2703         ccg.cylinders = 0;
2704         xpt_action((union ccb*)&ccg);
2705         if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2706                 /*
2707                  * We don't know what went wrong here- but just pick
2708                  * a geometry so we don't have nasty things like divide
2709                  * by zero.
2710                  */
2711                 dp->heads = 255;
2712                 dp->secs_per_track = 255;
2713                 dp->cylinders = dp->sectors / (255 * 255);
2714                 if (dp->cylinders == 0) {
2715                         dp->cylinders = 1;
2716                 }
2717         } else {
2718                 dp->heads = ccg.heads;
2719                 dp->secs_per_track = ccg.secs_per_track;
2720                 dp->cylinders = ccg.cylinders;
2721         }
2722 }
2723
2724 static void
2725 dasendorderedtag(void *arg)
2726 {
2727         struct da_softc *softc = arg;
2728
2729         if (da_send_ordered) {
2730                 if ((softc->ordered_tag_count == 0) 
2731                  && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
2732                         softc->flags |= DA_FLAG_NEED_OTAG;
2733                 }
2734                 if (softc->outstanding_cmds > 0)
2735                         softc->flags &= ~DA_FLAG_WENT_IDLE;
2736
2737                 softc->ordered_tag_count = 0;
2738         }
2739         /* Queue us up again */
2740         callout_reset(&softc->sendordered_c,
2741             (da_default_timeout * hz) / DA_ORDEREDTAG_INTERVAL,
2742             dasendorderedtag, softc);
2743 }
2744
2745 /*
2746  * Step through all DA peripheral drivers, and if the device is still open,
2747  * sync the disk cache to physical media.
2748  */
2749 static void
2750 dashutdown(void * arg, int howto)
2751 {
2752         struct cam_periph *periph;
2753         struct da_softc *softc;
2754         int error;
2755
2756         TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
2757                 union ccb ccb;
2758
2759                 cam_periph_lock(periph);
2760                 softc = (struct da_softc *)periph->softc;
2761
2762                 /*
2763                  * We only sync the cache if the drive is still open, and
2764                  * if the drive is capable of it..
2765                  */
2766                 if (((softc->flags & DA_FLAG_OPEN) == 0)
2767                  || (softc->quirks & DA_Q_NO_SYNC_CACHE)) {
2768                         cam_periph_unlock(periph);
2769                         continue;
2770                 }
2771
2772                 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
2773
2774                 ccb.ccb_h.ccb_state = DA_CCB_DUMP;
2775                 scsi_synchronize_cache(&ccb.csio,
2776                                        /*retries*/0,
2777                                        /*cbfcnp*/dadone,
2778                                        MSG_SIMPLE_Q_TAG,
2779                                        /*begin_lba*/0, /* whole disk */
2780                                        /*lb_count*/0,
2781                                        SSD_FULL_SIZE,
2782                                        60 * 60 * 1000);
2783
2784                 xpt_polled_action(&ccb);
2785
2786                 error = cam_periph_error(&ccb,
2787                     0, SF_NO_RECOVERY | SF_NO_RETRY | SF_QUIET_IR, NULL);
2788                 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
2789                         cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
2790                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
2791                 if (error != 0)
2792                         xpt_print(periph->path, "Synchronize cache failed\n");
2793                 cam_periph_unlock(periph);
2794         }
2795 }
2796
2797 #else /* !_KERNEL */
2798
2799 /*
2800  * XXX This is only left out of the kernel build to silence warnings.  If,
2801  * for some reason this function is used in the kernel, the ifdefs should
2802  * be moved so it is included both in the kernel and userland.
2803  */
2804 void
2805 scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
2806                  void (*cbfcnp)(struct cam_periph *, union ccb *),
2807                  u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
2808                  u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
2809                  u_int32_t timeout)
2810 {
2811         struct scsi_format_unit *scsi_cmd;
2812
2813         scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
2814         scsi_cmd->opcode = FORMAT_UNIT;
2815         scsi_cmd->byte2 = byte2;
2816         scsi_ulto2b(ileave, scsi_cmd->interleave);
2817
2818         cam_fill_csio(csio,
2819                       retries,
2820                       cbfcnp,
2821                       /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
2822                       tag_action,
2823                       data_ptr,
2824                       dxfer_len,
2825                       sense_len,
2826                       sizeof(*scsi_cmd),
2827                       timeout);
2828 }
2829
2830 #endif /* _KERNEL */