Merge branch 'vendor/GDB'
[dragonfly.git] / sys / bus / 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  * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.46 2003/10/21 22:18:19 thomas Exp $
29  */
30
31 #include <sys/param.h>
32 #include <sys/bootmaj.h>
33
34 #ifdef _KERNEL
35
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/buf.h>
39 #include <sys/sysctl.h>
40 #include <sys/taskqueue.h>
41 #include <sys/lock.h>
42 #include <sys/conf.h>
43 #include <sys/devicestat.h>
44 #include <sys/disk.h>
45 #include <sys/dtype.h>
46 #include <sys/eventhandler.h>
47 #include <sys/malloc.h>
48 #include <sys/cons.h>
49 #include <sys/proc.h>
50
51 #include <sys/buf2.h>
52 #include <sys/thread2.h>
53 #include <sys/mplock2.h>
54
55 #endif /* _KERNEL */
56
57 #ifdef _KERNEL
58 #include <vm/pmap.h>
59 #endif
60
61 #ifndef _KERNEL
62 #include <stdio.h>
63 #include <string.h>
64 #endif /* _KERNEL */
65
66 #include <sys/camlib.h>
67 #include "../cam.h"
68 #include "../cam_ccb.h"
69 #include "../cam_extend.h"
70 #include "../cam_periph.h"
71 #include "../cam_xpt_periph.h"
72 #include "../cam_sim.h"
73
74 #include "scsi_message.h"
75
76 #ifndef _KERNEL 
77 #include "scsi_da.h"
78 #endif /* !_KERNEL */
79
80 #ifdef _KERNEL
81 typedef enum {
82         DA_STATE_PROBE,
83         DA_STATE_PROBE2,
84         DA_STATE_NORMAL
85 } da_state;
86
87 typedef enum {
88         DA_FLAG_PACK_INVALID    = 0x001,
89         DA_FLAG_NEW_PACK        = 0x002,
90         DA_FLAG_PACK_LOCKED     = 0x004,
91         DA_FLAG_PACK_REMOVABLE  = 0x008,
92         DA_FLAG_TAGGED_QUEUING  = 0x010,
93         DA_FLAG_NEED_OTAG       = 0x020,
94         DA_FLAG_WENT_IDLE       = 0x040,
95         DA_FLAG_RETRY_UA        = 0x080,
96         DA_FLAG_OPEN            = 0x100,
97         DA_FLAG_SCTX_INIT       = 0x200,
98         DA_FLAG_RD_LIMIT        = 0x400,
99         DA_FLAG_WR_LIMIT        = 0x800
100 } da_flags;
101
102 typedef enum {
103         DA_Q_NONE               = 0x00,
104         DA_Q_NO_SYNC_CACHE      = 0x01,
105         DA_Q_NO_6_BYTE          = 0x02,
106         DA_Q_NO_PREVENT         = 0x04
107 } da_quirks;
108
109 typedef enum {
110         DA_CCB_PROBE            = 0x01,
111         DA_CCB_PROBE2           = 0x02,
112         DA_CCB_BUFFER_IO        = 0x03,
113         DA_CCB_WAITING          = 0x04,
114         DA_CCB_DUMP             = 0x05,
115         DA_CCB_TYPE_MASK        = 0x0F,
116         DA_CCB_RETRY_UA         = 0x10
117 } da_ccb_state;
118
119 /* Offsets into our private area for storing information */
120 #define ccb_state       ppriv_field0
121 #define ccb_bio         ppriv_ptr1
122
123 struct disk_params {
124         u_int8_t  heads;
125         u_int32_t cylinders;
126         u_int8_t  secs_per_track;
127         u_int32_t secsize;      /* Number of bytes/sector */
128         u_int64_t sectors;      /* total number sectors */
129 };
130
131 struct da_softc {
132         struct   bio_queue_head bio_queue_rd;
133         struct   bio_queue_head bio_queue_wr;
134         struct   devstat device_stats;
135         SLIST_ENTRY(da_softc) links;
136         LIST_HEAD(, ccb_hdr) pending_ccbs;
137         da_state state;
138         da_flags flags; 
139         da_quirks quirks;
140         int      minimum_cmd_size;
141         int      ordered_tag_count;
142         int      outstanding_cmds_rd;
143         int      outstanding_cmds_wr;
144         struct   disk_params params;
145         struct   disk disk;
146         union    ccb saved_ccb;
147         struct task             sysctl_task;
148         struct sysctl_ctx_list  sysctl_ctx;
149         struct sysctl_oid       *sysctl_tree;
150         struct callout          sendordered_c;
151 };
152
153 struct da_quirk_entry {
154         struct scsi_inquiry_pattern inq_pat;
155         da_quirks quirks;
156 };
157
158 static const char quantum[] = "QUANTUM";
159 static const char microp[] = "MICROP";
160
161 static struct da_quirk_entry da_quirk_table[] =
162 {
163         /* SPI, FC devices */
164         {
165                 /*
166                  * Fujitsu M2513A MO drives.
167                  * Tested devices: M2513A2 firmware versions 1200 & 1300.
168                  * (dip switch selects whether T_DIRECT or T_OPTICAL device)
169                  * Reported by: W.Scholten <whs@xs4all.nl>
170                  */
171                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
172                 /*quirks*/ DA_Q_NO_SYNC_CACHE
173         },
174         {
175                 /* See above. */
176                 {T_OPTICAL, SIP_MEDIA_REMOVABLE, "FUJITSU", "M2513A", "*"},
177                 /*quirks*/ DA_Q_NO_SYNC_CACHE
178         },
179         {
180                 /*
181                  * This particular Fujitsu drive doesn't like the
182                  * synchronize cache command.
183                  * Reported by: Tom Jackson <toj@gorilla.net>
184                  */
185                 {T_DIRECT, SIP_MEDIA_FIXED, "FUJITSU", "M2954*", "*"},
186                 /*quirks*/ DA_Q_NO_SYNC_CACHE
187         },
188         {
189                 /*
190                  * This drive doesn't like the synchronize cache command
191                  * either.  Reported by: Matthew Jacob <mjacob@feral.com>
192                  * in NetBSD PR kern/6027, August 24, 1998.
193                  */
194                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2217*", "*"},
195                 /*quirks*/ DA_Q_NO_SYNC_CACHE
196         },
197         {
198                 /*
199                  * This drive doesn't like the synchronize cache command
200                  * either.  Reported by: Hellmuth Michaelis (hm@kts.org)
201                  * (PR 8882).
202                  */
203                 {T_DIRECT, SIP_MEDIA_FIXED, microp, "2112*", "*"},
204                 /*quirks*/ DA_Q_NO_SYNC_CACHE
205         },
206         {
207                 /*
208                  * Doesn't like the synchronize cache command.
209                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
210                  */
211                 {T_DIRECT, SIP_MEDIA_FIXED, "NEC", "D3847*", "*"},
212                 /*quirks*/ DA_Q_NO_SYNC_CACHE
213         },
214         {
215                 /*
216                  * Doesn't like the synchronize cache command.
217                  * Reported by: Blaz Zupan <blaz@gold.amis.net>
218                  */
219                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "MAVERICK 540S", "*"},
220                 /*quirks*/ DA_Q_NO_SYNC_CACHE
221         },
222         {
223                 /*
224                  * Doesn't like the synchronize cache command.
225                  */
226                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS525S", "*"},
227                 /*quirks*/ DA_Q_NO_SYNC_CACHE
228         },
229         {
230                 /*
231                  * Doesn't like the synchronize cache command.
232                  * Reported by: walter@pelissero.de
233                  */
234                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "LPS540S", "*"},
235                 /*quirks*/ DA_Q_NO_SYNC_CACHE
236         },
237         {
238                 /*
239                  * Doesn't work correctly with 6 byte reads/writes.
240                  * Returns illegal request, and points to byte 9 of the
241                  * 6-byte CDB.
242                  * Reported by:  Adam McDougall <bsdx@spawnet.com>
243                  */
244                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 4*", "*"},
245                 /*quirks*/ DA_Q_NO_6_BYTE
246         },
247         {
248                 /* See above. */
249                 {T_DIRECT, SIP_MEDIA_FIXED, quantum, "VIKING 2*", "*"},
250                 /*quirks*/ DA_Q_NO_6_BYTE
251         },
252         {
253                 /*
254                  * Doesn't like the synchronize cache command.
255                  * Reported by: walter@pelissero.de
256                  */
257                 {T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CP3500*", "*"},
258                 /*quirks*/ DA_Q_NO_SYNC_CACHE
259         },
260         {
261                 /*
262                  * The CISS RAID controllers do not support SYNC_CACHE
263                  */
264                 {T_DIRECT, SIP_MEDIA_FIXED, "COMPAQ", "RAID*", "*"},
265                 /*quirks*/ DA_Q_NO_SYNC_CACHE
266         },
267         {
268                 /*
269                  * The same goes for the mly(4) controllers
270                  */
271                 {T_DIRECT, SIP_MEDIA_FIXED, "MLY*", "*", "MYLX"},
272                 /*quirks*/ DA_Q_NO_SYNC_CACHE
273         },
274         /*
275          * USB mass storage devices supported by umass(4)
276          *
277          * NOTE: USB attachments automatically set DA_Q_NO_SYNC_CACHE so
278          *       it does not have to be specified here.
279          */
280         {
281                 /*
282                  * Creative Nomad MUVO mp3 player (USB)
283                  * PR: kern/53094
284                  */
285                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "NOMAD_MUVO", "*"},
286                 /*quirks*/ DA_Q_NO_PREVENT
287         },
288         {
289                 /*
290                  * Sigmatel USB Flash MP3 Player
291                  * PR: kern/57046
292                  */
293                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SigmaTel", "MSCN", "*"},
294                 /*quirks*/ DA_Q_NO_PREVENT
295         },
296         {
297                 /*
298                  * SEAGRAND NP-900 MP3 Player
299                  * PR: kern/64563
300                  */
301                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "SEAGRAND", "NP-900*", "*"},
302                 /*quirks*/ DA_Q_NO_PREVENT
303         },
304         {
305                 /*
306                  * Creative MUVO Slim mp3 player (USB)
307                  * PR: usb/86131
308                  */
309                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "CREATIVE", "MuVo Slim",
310                 "*"}, /*quirks*/ DA_Q_NO_PREVENT
311         },
312         {
313                 /*
314                  * Philips USB Key Audio KEY013
315                  * PR: usb/68412
316                  */
317                 {T_DIRECT, SIP_MEDIA_REMOVABLE, "PHILIPS", "Key*", "*"},
318                 /*quirks*/ DA_Q_NO_PREVENT
319         },
320 };
321
322 static  d_open_t        daopen;
323 static  d_close_t       daclose;
324 static  d_strategy_t    dastrategy;
325 static  d_dump_t        dadump;
326 static  periph_init_t   dainit;
327 static  void            daasync(void *callback_arg, u_int32_t code,
328                                 struct cam_path *path, void *arg);
329 static  int             dacmdsizesysctl(SYSCTL_HANDLER_ARGS);
330 static  periph_ctor_t   daregister;
331 static  periph_dtor_t   dacleanup;
332 static  periph_start_t  dastart;
333 static  periph_oninv_t  daoninvalidate;
334 static  void            dadone(struct cam_periph *periph,
335                                union ccb *done_ccb);
336 static  int             daerror(union ccb *ccb, u_int32_t cam_flags,
337                                 u_int32_t sense_flags);
338 static void             daprevent(struct cam_periph *periph, int action);
339 static int              dagetcapacity(struct cam_periph *periph);
340 static int              dacheckmedia(struct cam_periph *periph);
341 static void             dasetgeom(struct cam_periph *periph, uint32_t block_len,
342                                   uint64_t maxsector);
343 static void             daflushbioq(struct bio_queue_head *bioq, int error);
344 static timeout_t        dasendorderedtag;
345 static void             dashutdown(void *arg, int howto);
346
347 #ifndef DA_DEFAULT_TIMEOUT
348 #define DA_DEFAULT_TIMEOUT 60   /* Timeout in seconds */
349 #endif
350
351 #ifndef DA_DEFAULT_RETRY
352 #define DA_DEFAULT_RETRY        4
353 #endif
354
355 #ifndef DA_DEFAULT_SEND_ORDERED
356 #define DA_DEFAULT_SEND_ORDERED 1
357 #endif
358
359 static int da_retry_count = DA_DEFAULT_RETRY;
360 static int da_default_timeout = DA_DEFAULT_TIMEOUT;
361 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
362 static struct callout dasendorderedtag_ch;
363
364 SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
365             "CAM Direct Access Disk driver");
366 SYSCTL_INT(_kern_cam_da, OID_AUTO, retry_count, CTLFLAG_RW,
367            &da_retry_count, 0, "Normal I/O retry count");
368 TUNABLE_INT("kern.cam.da.retry_count", &da_retry_count);
369 SYSCTL_INT(_kern_cam_da, OID_AUTO, default_timeout, CTLFLAG_RW,
370            &da_default_timeout, 0, "Normal I/O timeout (in seconds)");
371 TUNABLE_INT("kern.cam.da.default_timeout", &da_default_timeout);
372 SYSCTL_INT(_kern_cam_da, OID_AUTO, da_send_ordered, CTLFLAG_RW,
373            &da_send_ordered, 0, "Send Ordered Tags");
374 TUNABLE_INT("kern.cam.da.da_send_ordered", &da_send_ordered);
375
376 /*
377  * DA_ORDEREDTAG_INTERVAL determines how often, relative
378  * to the default timeout, we check to see whether an ordered
379  * tagged transaction is appropriate to prevent simple tag
380  * starvation.  Since we'd like to ensure that there is at least
381  * 1/2 of the timeout length left for a starved transaction to
382  * complete after we've sent an ordered tag, we must poll at least
383  * four times in every timeout period.  This takes care of the worst
384  * case where a starved transaction starts during an interval that
385  * meets the requirement "don't send an ordered tag" test so it takes
386  * us two intervals to determine that a tag must be sent.
387  */
388 #ifndef DA_ORDEREDTAG_INTERVAL
389 #define DA_ORDEREDTAG_INTERVAL 4
390 #endif
391
392 static struct periph_driver dadriver =
393 {
394         dainit, "da",
395         TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
396 };
397
398 PERIPHDRIVER_DECLARE(da, dadriver);
399
400 static struct dev_ops da_ops = {
401         { "da", DA_CDEV_MAJOR, D_DISK | D_MPSAFE },
402         .d_open =       daopen,
403         .d_close =      daclose,
404         .d_read =       physread,
405         .d_write =      physwrite,
406         .d_strategy =   dastrategy,
407         .d_dump =       dadump
408 };
409
410 static struct extend_array *daperiphs;
411
412 MALLOC_DEFINE(M_SCSIDA, "scsi_da", "scsi_da buffers");
413
414 static int
415 daopen(struct dev_open_args *ap)
416 {
417         cdev_t dev = ap->a_head.a_dev;
418         struct cam_periph *periph;
419         struct da_softc *softc;
420         struct disk_info info;
421         int unit;
422         int error;
423
424         unit = dkunit(dev);
425         periph = cam_extend_get(daperiphs, unit);
426         if (periph == NULL) {
427                 return (ENXIO); 
428         }
429
430         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
431                 return(ENXIO);
432         }
433
434         cam_periph_lock(periph);
435         if ((error = cam_periph_hold(periph, PCATCH)) != 0) {
436                 cam_periph_unlock(periph);
437                 cam_periph_release(periph);
438                 return (error);
439         }
440
441         unit = periph->unit_number;
442         softc = (struct da_softc *)periph->softc;
443
444         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE,
445             ("daopen: dev=%s (unit %d)\n", devtoname(dev),
446              unit));
447
448         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
449                 /* Invalidate our pack information. */
450                 disk_invalidate(&softc->disk);
451                 softc->flags &= ~DA_FLAG_PACK_INVALID;
452         }
453
454         error = dacheckmedia(periph);
455         softc->flags |= DA_FLAG_OPEN;
456
457         if (error == 0) {
458                 struct ccb_getdev cgd;
459
460                 /* Build disk information structure */
461                 bzero(&info, sizeof(info));
462                 info.d_type = DTYPE_SCSI;
463
464                 /*
465                  * Grab the inquiry data to get the vendor and product names.
466                  * Put them in the typename and packname for the label.
467                  */
468                 xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1);
469                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
470                 xpt_action((union ccb *)&cgd);
471
472                 /*
473                  * Check to see whether or not the blocksize is set yet.
474                  * If it isn't, set it and then clear the blocksize
475                  * unavailable flag for the device statistics.
476                  */
477                 if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0){
478                         softc->device_stats.block_size = softc->params.secsize;
479                         softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
480                 }
481         }
482         
483         if (error == 0) {
484                 if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0 &&
485                     (softc->quirks & DA_Q_NO_PREVENT) == 0)
486                         daprevent(periph, PR_PREVENT);
487         } else {
488                 softc->flags &= ~DA_FLAG_OPEN;
489                 cam_periph_release(periph);
490         }
491         cam_periph_unhold(periph, 1);
492         return (error);
493 }
494
495 static int
496 daclose(struct dev_close_args *ap)
497 {
498         cdev_t dev = ap->a_head.a_dev;
499         struct  cam_periph *periph;
500         struct  da_softc *softc;
501         int     unit;
502         int     error;
503
504         unit = dkunit(dev);
505         periph = cam_extend_get(daperiphs, unit);
506         if (periph == NULL)
507                 return (ENXIO); 
508
509         cam_periph_lock(periph);
510         if ((error = cam_periph_hold(periph, 0)) != 0) {
511                 cam_periph_unlock(periph);
512                 cam_periph_release(periph);
513                 return (error);
514         }
515
516         softc = (struct da_softc *)periph->softc;
517
518         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
519                 union   ccb *ccb;
520
521                 ccb = cam_periph_getccb(periph, /*priority*/1);
522
523                 scsi_synchronize_cache(&ccb->csio,
524                                        /*retries*/1,
525                                        /*cbfcnp*/dadone,
526                                        MSG_SIMPLE_Q_TAG,
527                                        /*begin_lba*/0,/* Cover the whole disk */
528                                        /*lb_count*/0,
529                                        SSD_FULL_SIZE,
530                                        5 * 60 * 1000);
531
532                 cam_periph_runccb(ccb, /*error_routine*/NULL, /*cam_flags*/0,
533                                   /*sense_flags*/SF_RETRY_UA,
534                                   &softc->device_stats);
535
536                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
537                         if ((ccb->ccb_h.status & CAM_STATUS_MASK) ==
538                              CAM_SCSI_STATUS_ERROR) {
539                                 int asc, ascq;
540                                 int sense_key, error_code;
541
542                                 scsi_extract_sense(&ccb->csio.sense_data,
543                                                    &error_code,
544                                                    &sense_key, 
545                                                    &asc, &ascq);
546                                 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
547                                         scsi_sense_print(&ccb->csio);
548                         } else {
549                                 xpt_print(periph->path, "Synchronize cache "
550                                     "failed, status == 0x%x, scsi status == "
551                                     "0x%x\n", ccb->csio.ccb_h.status,
552                                     ccb->csio.scsi_status);
553                         }
554                 }
555
556                 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
557                         cam_release_devq(ccb->ccb_h.path,
558                                          /*relsim_flags*/0,
559                                          /*reduction*/0,
560                                          /*timeout*/0,
561                                          /*getcount_only*/0);
562
563                 xpt_release_ccb(ccb);
564
565         }
566
567         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) {
568                 if ((softc->quirks & DA_Q_NO_PREVENT) == 0)
569                         daprevent(periph, PR_ALLOW);
570                 /*
571                  * If we've got removeable media, mark the blocksize as
572                  * unavailable, since it could change when new media is
573                  * inserted.
574                  */
575                 softc->device_stats.flags |= DEVSTAT_BS_UNAVAILABLE;
576         }
577
578         /*
579          * Don't compound any ref counting software bugs with more.
580          */
581         if (softc->flags & DA_FLAG_OPEN) {
582                 softc->flags &= ~DA_FLAG_OPEN;
583                 cam_periph_release(periph);
584         } else {
585                 xpt_print(periph->path,
586                           "daclose() called on an already closed device!\n");
587         }
588         cam_periph_unhold(periph, 1);
589         return (0);     
590 }
591
592 /*
593  * Actually translate the requested transfer into one the physical driver
594  * can understand.  The transfer is described by a buf and will include
595  * only one physical transfer.
596  */
597 static int
598 dastrategy(struct dev_strategy_args *ap)
599 {
600         cdev_t dev = ap->a_head.a_dev;
601         struct bio *bio = ap->a_bio;
602         struct buf *bp = bio->bio_buf;
603         struct cam_periph *periph;
604         struct da_softc *softc;
605         u_int  unit;
606         u_int  part;
607         
608         unit = dkunit(dev);
609         part = dkpart(dev);
610         periph = cam_extend_get(daperiphs, unit);
611         if (periph == NULL) {
612                 bp->b_error = ENXIO;
613                 goto bad;               
614         }
615         softc = (struct da_softc *)periph->softc;
616
617         cam_periph_lock(periph);
618
619 #if 0
620         /*
621          * check it's not too big a transfer for our adapter
622          */
623         scsi_minphys(bp, &sd_switch);
624 #endif
625
626         /*
627          * Mask interrupts so that the pack cannot be invalidated until
628          * after we are in the queue.  Otherwise, we might not properly
629          * clean up one of the buffers.
630          */
631         
632         /*
633          * If the device has been made invalid, error out
634          */
635         if ((softc->flags & DA_FLAG_PACK_INVALID)) {
636                 cam_periph_unlock(periph);
637                 bp->b_error = ENXIO;
638                 goto bad;
639         }
640         
641         /*
642          * Place it in the queue of disk activities for this disk
643          */
644         if (bp->b_cmd == BUF_CMD_WRITE || bp->b_cmd == BUF_CMD_FLUSH)
645                 bioqdisksort(&softc->bio_queue_wr, bio);
646         else
647                 bioqdisksort(&softc->bio_queue_rd, bio);
648         
649         /*
650          * Schedule ourselves for performing the work.
651          */
652         xpt_schedule(periph, /* XXX priority */1);
653         cam_periph_unlock(periph);
654
655         return(0);
656 bad:
657         bp->b_flags |= B_ERROR;
658
659         /*
660          * Correctly set the buf to indicate a completed xfer
661          */
662         bp->b_resid = bp->b_bcount;
663         biodone(bio);
664         return(0);
665 }
666
667 static int
668 dadump(struct dev_dump_args *ap)
669 {
670         cdev_t dev = ap->a_head.a_dev;
671         struct      cam_periph *periph;
672         struct      da_softc *softc;
673         u_int       unit;
674         u_int32_t   secsize;
675         struct      ccb_scsiio csio;
676
677         unit = dkunit(dev);
678         periph = cam_extend_get(daperiphs, unit);
679         if (periph == NULL)
680                 return (ENXIO);
681
682         softc = (struct da_softc *)periph->softc;
683         cam_periph_lock(periph);
684         secsize = softc->params.secsize; /* XXX: or ap->a_secsize? */
685
686         if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) {
687                 cam_periph_unlock(periph);
688                 return (ENXIO);
689         }
690
691         /*
692          * because length == 0 means we are supposed to flush cache, we only
693          * try to write something if length > 0.
694          */
695         if (ap->a_length > 0) {
696                 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
697                 csio.ccb_h.flags |= CAM_POLLED;
698                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
699                 scsi_read_write(&csio,
700                                 /*retries*/1,
701                                 dadone,
702                                 MSG_ORDERED_Q_TAG,
703                                 /*read*/FALSE,
704                                 /*byte2*/0,
705                                 /*minimum_cmd_size*/ softc->minimum_cmd_size,
706                                 ap->a_offset / secsize,
707                                 ap->a_length / secsize,
708                                 /*data_ptr*/(u_int8_t *) ap->a_virtual,
709                                 /*dxfer_len*/ap->a_length,
710                                 /*sense_len*/SSD_FULL_SIZE,
711                                 DA_DEFAULT_TIMEOUT * 1000);             
712                 xpt_polled_action((union ccb *)&csio);
713
714                 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
715                         kprintf("Aborting dump due to I/O error.\n");
716                         if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
717                              CAM_SCSI_STATUS_ERROR)
718                                 scsi_sense_print(&csio);
719                         else
720                                 kprintf("status == 0x%x, scsi status == 0x%x\n",
721                                        csio.ccb_h.status, csio.scsi_status);
722                         return(EIO);
723                 }
724                 cam_periph_unlock(periph);
725                 return 0;
726         }
727
728         /*
729          * Sync the disk cache contents to the physical media.
730          */
731         if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) {
732
733                 xpt_setup_ccb(&csio.ccb_h, periph->path, /*priority*/1);
734                 csio.ccb_h.ccb_state = DA_CCB_DUMP;
735                 scsi_synchronize_cache(&csio,
736                                        /*retries*/1,
737                                        /*cbfcnp*/dadone,
738                                        MSG_SIMPLE_Q_TAG,
739                                        /*begin_lba*/0,/* Cover the whole disk */
740                                        /*lb_count*/0,
741                                        SSD_FULL_SIZE,
742                                        5 * 60 * 1000);
743                 xpt_polled_action((union ccb *)&csio);
744
745                 if ((csio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
746                         if ((csio.ccb_h.status & CAM_STATUS_MASK) ==
747                              CAM_SCSI_STATUS_ERROR) {
748                                 int asc, ascq;
749                                 int sense_key, error_code;
750
751                                 scsi_extract_sense(&csio.sense_data,
752                                                    &error_code,
753                                                    &sense_key, 
754                                                    &asc, &ascq);
755                                 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
756                                         scsi_sense_print(&csio);
757                         } else {
758                                 xpt_print(periph->path, "Synchronize cache "
759                                     "failed, status == 0x%x, scsi status == "
760                                     "0x%x\n", csio.ccb_h.status,
761                                     csio.scsi_status);
762                         }
763                 }
764         }
765         cam_periph_unlock(periph);
766         return (0);
767 }
768
769 static void
770 dainit(void)
771 {
772         cam_status status;
773
774         /*
775          * Create our extend array for storing the devices we attach to.
776          */
777         daperiphs = cam_extend_new();
778         if (daperiphs == NULL) {
779                 kprintf("da: Failed to alloc extend array!\n");
780                 return;
781         }
782
783         callout_init(&dasendorderedtag_ch);
784
785         /*
786          * Install a global async callback.  This callback will
787          * receive async callbacks like "new device found".
788          */
789         status = xpt_register_async(AC_FOUND_DEVICE, daasync, NULL, NULL);
790
791         if (status != CAM_REQ_CMP) {
792                 kprintf("da: Failed to attach master async callback "
793                        "due to status 0x%x!\n", status);
794         } else if (da_send_ordered) {
795
796                 /* Register our shutdown event handler */
797                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, dashutdown, 
798                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
799                     kprintf("dainit: shutdown event registration failed!\n");
800         }
801 }
802
803 static void
804 daoninvalidate(struct cam_periph *periph)
805 {
806         struct da_softc *softc;
807
808         softc = (struct da_softc *)periph->softc;
809
810         /*
811          * De-register any async callbacks.
812          */
813         xpt_register_async(0, daasync, periph, periph->path);
814
815         softc->flags |= DA_FLAG_PACK_INVALID;
816
817         /*
818          * Return all queued I/O with ENXIO.
819          * XXX Handle any transactions queued to the card
820          *     with XPT_ABORT_CCB.
821          */
822         daflushbioq(&softc->bio_queue_wr, ENXIO);
823         daflushbioq(&softc->bio_queue_rd, ENXIO);
824         xpt_print(periph->path, "lost device\n");
825 }
826
827 static void
828 daflushbioq(struct bio_queue_head *bioq, int error)
829 {
830         struct bio *q_bio;
831         struct buf *q_bp;
832
833         while ((q_bio = bioq_first(bioq)) != NULL){
834                 bioq_remove(bioq, q_bio);
835                 q_bp = q_bio->bio_buf;
836                 q_bp->b_resid = q_bp->b_bcount;
837                 q_bp->b_error = error;
838                 q_bp->b_flags |= B_ERROR;
839                 biodone(q_bio);
840         }
841 }
842
843 static void
844 dacleanup(struct cam_periph *periph)
845 {
846         struct da_softc *softc;
847
848         softc = (struct da_softc *)periph->softc;
849
850         devstat_remove_entry(&softc->device_stats);
851         cam_extend_release(daperiphs, periph->unit_number);
852         xpt_print(periph->path, "removing device entry\n");
853         /*
854          * If we can't free the sysctl tree, oh well...
855          */
856         if ((softc->flags & DA_FLAG_SCTX_INIT) != 0
857             && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
858                 xpt_print(periph->path, "can't remove sysctl context\n");
859         }
860         periph->softc = NULL;
861         if (softc->disk.d_rawdev) {
862                 cam_periph_unlock(periph);
863                 disk_destroy(&softc->disk);
864                 cam_periph_lock(periph);
865         }
866
867         callout_stop(&softc->sendordered_c);
868         kfree(softc, M_DEVBUF);
869 }
870
871 static void
872 daasync(void *callback_arg, u_int32_t code,
873         struct cam_path *path, void *arg)
874 {
875         struct cam_periph *periph;
876
877         periph = (struct cam_periph *)callback_arg;
878
879         switch (code) {
880         case AC_FOUND_DEVICE:
881         {
882                 struct ccb_getdev *cgd;
883                 struct cam_sim *sim;
884                 cam_status status;
885  
886                 cgd = (struct ccb_getdev *)arg;
887                 if (cgd == NULL)
888                         break;
889
890                 if (SID_TYPE(&cgd->inq_data) != T_DIRECT
891                     && SID_TYPE(&cgd->inq_data) != T_RBC
892                     && SID_TYPE(&cgd->inq_data) != T_OPTICAL)
893                         break;
894
895                 /*
896                  * Don't complain if a valid peripheral is already attached.
897                  */
898                 periph = cam_periph_find(cgd->ccb_h.path, "da");
899                 if (periph && (periph->flags & CAM_PERIPH_INVALID) == 0)
900                         break;
901
902                 /*
903                  * Allocate a peripheral instance for
904                  * this device and start the probe
905                  * process.
906                  */
907                 sim = xpt_path_sim(cgd->ccb_h.path);
908                 status = cam_periph_alloc(daregister, daoninvalidate,
909                                           dacleanup, dastart,
910                                           "da", CAM_PERIPH_BIO,
911                                           cgd->ccb_h.path, daasync,
912                                           AC_FOUND_DEVICE, cgd);
913
914                 if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) {
915                         kprintf("daasync: Unable to attach to new device "
916                                 "due to status 0x%x\n", status);
917                 }
918                 break;
919         }
920         case AC_SENT_BDR:
921         case AC_BUS_RESET:
922         {
923                 struct da_softc *softc;
924                 struct ccb_hdr *ccbh;
925
926                 softc = (struct da_softc *)periph->softc;
927                 /*
928                  * Don't fail on the expected unit attention
929                  * that will occur.
930                  */
931                 softc->flags |= DA_FLAG_RETRY_UA;
932                 LIST_FOREACH(ccbh, &softc->pending_ccbs, periph_links.le)
933                         ccbh->ccb_state |= DA_CCB_RETRY_UA;
934                 /* FALLTHROUGH*/
935         }
936         default:
937                 cam_periph_async(periph, code, path, arg);
938                 break;
939         }
940 }
941
942 static void
943 dasysctlinit(void *context, int pending)
944 {
945         struct cam_periph *periph;
946         struct da_softc *softc;
947         char tmpstr[80], tmpstr2[80];
948
949         get_mplock();
950         periph = (struct cam_periph *)context;
951         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
952                 rel_mplock();
953                 return;
954         }
955
956         softc = (struct da_softc *)periph->softc;
957         ksnprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number);
958         ksnprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
959
960         sysctl_ctx_init(&softc->sysctl_ctx);
961         softc->flags |= DA_FLAG_SCTX_INIT;
962         softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
963                 SYSCTL_STATIC_CHILDREN(_kern_cam_da), OID_AUTO, tmpstr2,
964                 CTLFLAG_RD, 0, tmpstr);
965         if (softc->sysctl_tree == NULL) {
966                 kprintf("dasysctlinit: unable to allocate sysctl tree\n");
967                 cam_periph_release(periph);
968                 rel_mplock();
969                 return;
970         }
971
972         /*
973          * Now register the sysctl handler, so the user can the value on
974          * the fly.
975          */
976         SYSCTL_ADD_PROC(&softc->sysctl_ctx,SYSCTL_CHILDREN(softc->sysctl_tree),
977                 OID_AUTO, "minimum_cmd_size", CTLTYPE_INT | CTLFLAG_RW,
978                 &softc->minimum_cmd_size, 0, dacmdsizesysctl, "I",
979                 "Minimum CDB size");
980
981         cam_periph_release(periph);
982         rel_mplock();
983 }
984
985 static int
986 dacmdsizesysctl(SYSCTL_HANDLER_ARGS)
987 {
988         int error, value;
989
990         value = *(int *)arg1;
991
992         error = sysctl_handle_int(oidp, &value, 0, req);
993
994         if ((error != 0)
995          || (req->newptr == NULL))
996                 return (error);
997
998         /*
999          * Acceptable values here are 6, 10 or 12, or 16.
1000          */
1001         if (value < 6)
1002                 value = 6;
1003         else if ((value > 6)
1004               && (value <= 10))
1005                 value = 10;
1006         else if ((value > 10)
1007               && (value <= 12))
1008                 value = 12;
1009         else if (value > 12)
1010                 value = 16;
1011
1012         *(int *)arg1 = value;
1013
1014         return (0);
1015 }
1016
1017 static cam_status
1018 daregister(struct cam_periph *periph, void *arg)
1019 {
1020         struct da_softc *softc;
1021         struct ccb_pathinq cpi;
1022         struct ccb_getdev *cgd;
1023         char tmpstr[80];
1024         caddr_t match;
1025
1026         cgd = (struct ccb_getdev *)arg;
1027         if (periph == NULL) {
1028                 kprintf("daregister: periph was NULL!!\n");
1029                 return(CAM_REQ_CMP_ERR);
1030         }
1031
1032         if (cgd == NULL) {
1033                 kprintf("daregister: no getdev CCB, can't register device\n");
1034                 return(CAM_REQ_CMP_ERR);
1035         }
1036
1037         softc = kmalloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO);
1038         LIST_INIT(&softc->pending_ccbs);
1039         softc->state = DA_STATE_PROBE;
1040         bioq_init(&softc->bio_queue_rd);
1041         bioq_init(&softc->bio_queue_wr);
1042         if (SID_IS_REMOVABLE(&cgd->inq_data))
1043                 softc->flags |= DA_FLAG_PACK_REMOVABLE;
1044         if ((cgd->inq_data.flags & SID_CmdQue) != 0)
1045                 softc->flags |= DA_FLAG_TAGGED_QUEUING;
1046
1047         periph->softc = softc;
1048         
1049         cam_extend_set(daperiphs, periph->unit_number, periph);
1050
1051         /*
1052          * See if this device has any quirks.
1053          */
1054         match = cam_quirkmatch((caddr_t)&cgd->inq_data,
1055                                (caddr_t)da_quirk_table,
1056                                sizeof(da_quirk_table)/sizeof(*da_quirk_table),
1057                                sizeof(*da_quirk_table), scsi_inquiry_match);
1058
1059         if (match != NULL)
1060                 softc->quirks = ((struct da_quirk_entry *)match)->quirks;
1061         else
1062                 softc->quirks = DA_Q_NONE;
1063
1064         /*
1065          * Unconditionally disable the synchronize cache command for
1066          * usb attachments.  It's just impossible to determine if the
1067          * device supports it or not and if it doesn't the port can
1068          * brick.
1069          */
1070         if (strncmp(periph->sim->sim_name, "umass", 4) == 0) {
1071                 softc->quirks |= DA_Q_NO_SYNC_CACHE;
1072         }
1073
1074         TASK_INIT(&softc->sysctl_task, 0, dasysctlinit, periph);
1075
1076         /* Check if the SIM does not want 6 byte commands */
1077         xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
1078         cpi.ccb_h.func_code = XPT_PATH_INQ;
1079         xpt_action((union ccb *)&cpi);
1080         if (cpi.ccb_h.status == CAM_REQ_CMP && (cpi.hba_misc & PIM_NO_6_BYTE))
1081                 softc->quirks |= DA_Q_NO_6_BYTE;
1082
1083         /*
1084          * RBC devices don't have to support READ(6), only READ(10).
1085          */
1086         if (softc->quirks & DA_Q_NO_6_BYTE || SID_TYPE(&cgd->inq_data) == T_RBC)
1087                 softc->minimum_cmd_size = 10;
1088         else
1089                 softc->minimum_cmd_size = 6;
1090
1091         /*
1092          * Load the user's default, if any.
1093          */
1094         ksnprintf(tmpstr, sizeof(tmpstr), "kern.cam.da.%d.minimum_cmd_size",
1095                  periph->unit_number);
1096         TUNABLE_INT_FETCH(tmpstr, &softc->minimum_cmd_size);
1097
1098         /*
1099          * 6, 10, 12, and 16 are the currently permissible values.
1100          */
1101         if (softc->minimum_cmd_size < 6)
1102                 softc->minimum_cmd_size = 6;
1103         else if ((softc->minimum_cmd_size > 6)
1104               && (softc->minimum_cmd_size <= 10))
1105                 softc->minimum_cmd_size = 10;
1106         else if ((softc->minimum_cmd_size > 10)
1107               && (softc->minimum_cmd_size <= 12))
1108                 softc->minimum_cmd_size = 12;
1109         else if (softc->minimum_cmd_size > 12)
1110                 softc->minimum_cmd_size = 16;
1111
1112         /*
1113          * The DA driver supports a blocksize, but
1114          * we don't know the blocksize until we do 
1115          * a read capacity.  So, set a flag to
1116          * indicate that the blocksize is 
1117          * unavailable right now.  We'll clear the
1118          * flag as soon as we've done a read capacity.
1119          */
1120         devstat_add_entry(&softc->device_stats, "da", 
1121                           periph->unit_number, 0,
1122                           DEVSTAT_BS_UNAVAILABLE,
1123                           SID_TYPE(&cgd->inq_data) | DEVSTAT_TYPE_IF_SCSI,
1124                           DEVSTAT_PRIORITY_DISK);
1125
1126         /*
1127          * Register this media as a disk
1128          */
1129         CAM_SIM_UNLOCK(periph->sim);
1130         disk_create(periph->unit_number, &softc->disk, &da_ops);
1131         softc->disk.d_rawdev->si_iosize_max = MAXPHYS;
1132         CAM_SIM_LOCK(periph->sim);
1133
1134         /*
1135          * Add async callbacks for bus reset and
1136          * bus device reset calls.  I don't bother
1137          * checking if this fails as, in most cases,
1138          * the system will function just fine without
1139          * them and the only alternative would be to
1140          * not attach the device on failure.
1141          */
1142         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE,
1143                            daasync, periph, periph->path);
1144
1145         /*
1146          * Take an exclusive refcount on the periph while dastart is called
1147          * to finish the probe.  The reference will be dropped in dadone at
1148          * the end of probe.
1149          */
1150         cam_periph_hold(periph, 0);
1151         xpt_schedule(periph, /*priority*/5);
1152
1153         /*
1154          * Schedule a periodic event to occasionally send an
1155          * ordered tag to a device.
1156          */
1157         callout_init(&softc->sendordered_c);
1158         callout_reset(&softc->sendordered_c,
1159             (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
1160             dasendorderedtag, softc);
1161
1162         return(CAM_REQ_CMP);
1163 }
1164
1165 static void
1166 dastart(struct cam_periph *periph, union ccb *start_ccb)
1167 {
1168         struct da_softc *softc;
1169
1170         softc = (struct da_softc *)periph->softc;
1171
1172         switch (softc->state) {
1173         case DA_STATE_NORMAL:
1174         {
1175                 /* Pull a buffer from the queue and get going on it */          
1176                 struct bio *bio;
1177                 struct bio *bio_rd;
1178                 struct bio *bio_wr;
1179                 struct buf *bp;
1180                 u_int8_t tag_code;
1181                 int limit;
1182
1183                 /*
1184                  * See if there is a buf with work for us to do..
1185                  */
1186                 bio_rd = bioq_first(&softc->bio_queue_rd);
1187                 bio_wr = bioq_first(&softc->bio_queue_wr);
1188
1189                 if (periph->immediate_priority <= periph->pinfo.priority) {
1190                         CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
1191                                         ("queuing for immediate ccb\n"));
1192                         start_ccb->ccb_h.ccb_state = DA_CCB_WAITING;
1193                         SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1194                                           periph_links.sle);
1195                         periph->immediate_priority = CAM_PRIORITY_NONE;
1196                         wakeup(&periph->ccb_list);
1197                         if (bio_rd || bio_wr) {
1198                                 /*
1199                                  * Have more work to do, so ensure we stay
1200                                  * scheduled
1201                                  */
1202                                 xpt_schedule(periph, /* XXX priority */1);
1203                         }
1204                         break;
1205                 }
1206
1207                 /*
1208                  * Select a read or write buffer to queue.  Limit the number
1209                  * of tags dedicated to reading or writing, giving reads
1210                  * precedence.
1211                  *
1212                  * Writes to modern hard drives go into the HDs cache and
1213                  * return completion nearly instantly.  That is until the
1214                  * cache becomes full.  When the HDs cache becomes full
1215                  * write commands will begin to stall.  If all available
1216                  * tags are taken up by writes which saturate the drive
1217                  * reads will become tag-starved.
1218                  *
1219                  * A similar situation can occur with reads.  With many
1220                  * parallel readers all tags can be taken up by reads
1221                  * and prevent any writes from draining, even if the HD's
1222                  * cache is not full.
1223                  */
1224                 limit = periph->sim->max_tagged_dev_openings * 2 / 3 + 1;
1225 #if 0
1226                 /* DEBUGGING */
1227                 static int savets;
1228                 static long savets2;
1229                 if (1 || time_second != savets2 || (ticks != savets && (softc->outstanding_cmds_rd || softc->outstanding_cmds_wr))) {
1230                         kprintf("%d %d (%d)\n",
1231                                 softc->outstanding_cmds_rd,
1232                                 softc->outstanding_cmds_wr,
1233                                 limit);
1234                         savets = ticks;
1235                         savets2 = time_second;
1236                 }
1237 #endif
1238                 if (bio_rd && softc->outstanding_cmds_rd < limit) {
1239                         bio = bio_rd;
1240                         bioq_remove(&softc->bio_queue_rd, bio);
1241                 } else if (bio_wr && softc->outstanding_cmds_wr < limit) {
1242                         bio = bio_wr;
1243                         bioq_remove(&softc->bio_queue_wr, bio);
1244                 } else {
1245                         if (bio_rd)
1246                                 softc->flags |= DA_FLAG_RD_LIMIT;
1247                         if (bio_wr)
1248                                 softc->flags |= DA_FLAG_WR_LIMIT;
1249                         xpt_release_ccb(start_ccb);
1250                         break;
1251                 }
1252
1253                 /*
1254                  * We can queue new work.
1255                  */
1256                 bp = bio->bio_buf;
1257
1258                 devstat_start_transaction(&softc->device_stats);
1259
1260                 if ((bp->b_flags & B_ORDERED) != 0 ||
1261                     (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
1262                         softc->flags &= ~DA_FLAG_NEED_OTAG;
1263                         softc->ordered_tag_count++;
1264                         tag_code = MSG_ORDERED_Q_TAG;
1265                 } else {
1266                         tag_code = MSG_SIMPLE_Q_TAG;
1267                 }
1268
1269                 switch(bp->b_cmd) {
1270                 case BUF_CMD_READ:
1271                 case BUF_CMD_WRITE:
1272                         /*
1273                          * Block read/write op
1274                          */
1275                         KKASSERT(bio->bio_offset % softc->params.secsize == 0);
1276
1277                         scsi_read_write(
1278                                 &start_ccb->csio,
1279                                 da_retry_count,         /* retries */
1280                                 dadone,
1281                                 tag_code,
1282                                 (bp->b_cmd == BUF_CMD_READ),
1283                                 0,                      /* byte2 */
1284                                 softc->minimum_cmd_size,
1285                                 bio->bio_offset / softc->params.secsize,
1286                                 bp->b_bcount / softc->params.secsize,
1287                                 bp->b_data,
1288                                 bp->b_bcount,
1289                                 SSD_FULL_SIZE,          /* sense_len */
1290                                 da_default_timeout * 1000
1291                         );
1292                         break;
1293                 case BUF_CMD_FLUSH:
1294                         /*
1295                          * Silently complete a flush request if the device
1296                          * cannot handle it.
1297                          */
1298                         if (softc->quirks & DA_Q_NO_SYNC_CACHE) {
1299                                 xpt_release_ccb(start_ccb);
1300                                 start_ccb = NULL;
1301                                 devstat_end_transaction_buf(
1302                                         &softc->device_stats, bp);
1303                                 biodone(bio);
1304                         } else {
1305                                 scsi_synchronize_cache(
1306                                         &start_ccb->csio,
1307                                         1,              /* retries */
1308                                         dadone,         /* cbfcnp */
1309                                         MSG_SIMPLE_Q_TAG,
1310                                         0,              /* lba */
1311                                         0,              /* count (whole disk) */
1312                                         SSD_FULL_SIZE,
1313                                         da_default_timeout*1000 /* timeout */
1314                                 );
1315                         }
1316                         break;
1317                 default:
1318                         xpt_release_ccb(start_ccb);
1319                         start_ccb = NULL;
1320                         panic("dastart: unrecognized bio cmd %d", bp->b_cmd);
1321                         break; /* NOT REACHED */
1322                 }
1323
1324                 /*
1325                  * Block out any asyncronous callbacks
1326                  * while we touch the pending ccb list.
1327                  */
1328                 if (start_ccb) {
1329                         start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
1330                         LIST_INSERT_HEAD(&softc->pending_ccbs,
1331                                          &start_ccb->ccb_h, periph_links.le);
1332                         if (bp->b_cmd == BUF_CMD_WRITE ||
1333                             bp->b_cmd == BUF_CMD_FLUSH) {
1334                                 ++softc->outstanding_cmds_wr;
1335                         } else {
1336                                 ++softc->outstanding_cmds_rd;
1337                         }
1338
1339                         /* We expect a unit attention from this device */
1340                         if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
1341                                 start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
1342                                 softc->flags &= ~DA_FLAG_RETRY_UA;
1343                         }
1344
1345                         start_ccb->ccb_h.ccb_bio = bio;
1346                         xpt_action(start_ccb);
1347                 }
1348                 
1349                 /*
1350                  * Be sure we stay scheduled if we have more work to do.
1351                  */
1352                 if (bioq_first(&softc->bio_queue_rd) ||
1353                     bioq_first(&softc->bio_queue_wr)) {
1354                         xpt_schedule(periph, 1);
1355                 }
1356                 break;
1357         }
1358         case DA_STATE_PROBE:
1359         {
1360                 struct ccb_scsiio *csio;
1361                 struct scsi_read_capacity_data *rcap;
1362
1363                 rcap = kmalloc(sizeof(*rcap), M_SCSIDA, M_INTWAIT | M_ZERO);
1364                 csio = &start_ccb->csio;
1365                 scsi_read_capacity(csio,
1366                                    /*retries*/4,
1367                                    dadone,
1368                                    MSG_SIMPLE_Q_TAG,
1369                                    rcap,
1370                                    SSD_FULL_SIZE,
1371                                    /*timeout*/5000);
1372                 start_ccb->ccb_h.ccb_bio = NULL;
1373                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE;
1374                 xpt_action(start_ccb);
1375                 break;
1376         }
1377         case DA_STATE_PROBE2:
1378         {
1379                 struct ccb_scsiio *csio;
1380                 struct scsi_read_capacity_data_16 *rcaplong;
1381
1382                 rcaplong = kmalloc(sizeof(*rcaplong), M_SCSIDA,
1383                                    M_INTWAIT | M_ZERO);
1384                 if (rcaplong == NULL) {
1385                         kprintf("dastart: Couldn't allocate read_capacity\n");
1386                         /* da_free_periph??? */
1387                         break;
1388                 }
1389                 csio = &start_ccb->csio;
1390                 scsi_read_capacity_16(csio,
1391                                     /*retries*/ 4,
1392                                     /*cbfcnp*/ dadone,
1393                                     /*tag_action*/ MSG_SIMPLE_Q_TAG,
1394                                     /*lba*/ 0,
1395                                     /*reladr*/ 0,
1396                                     /*pmi*/ 0,
1397                                     rcaplong,
1398                                     /*sense_len*/ SSD_FULL_SIZE,
1399                                     /*timeout*/ 60000);
1400                 start_ccb->ccb_h.ccb_bio = NULL;
1401                 start_ccb->ccb_h.ccb_state = DA_CCB_PROBE2;
1402                 xpt_action(start_ccb);  
1403                 break;
1404         }
1405         }
1406 }
1407
1408 static int
1409 cmd6workaround(union ccb *ccb)
1410 {
1411         struct scsi_rw_6 cmd6;
1412         struct scsi_rw_10 *cmd10;
1413         struct da_softc *softc;
1414         u_int8_t *cdb;
1415         int frozen;
1416
1417         cdb = ccb->csio.cdb_io.cdb_bytes;
1418
1419         /* Translation only possible if CDB is an array and cmd is R/W6 */
1420         if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0 ||
1421             (*cdb != READ_6 && *cdb != WRITE_6))
1422                 return 0;
1423
1424         xpt_print(ccb->ccb_h.path, "READ(6)/WRITE(6) not supported, "
1425             "increasing minimum_cmd_size to 10.\n");
1426         softc = (struct da_softc *)xpt_path_periph(ccb->ccb_h.path)->softc;
1427         softc->minimum_cmd_size = 10;
1428
1429         bcopy(cdb, &cmd6, sizeof(struct scsi_rw_6));
1430         cmd10 = (struct scsi_rw_10 *)cdb;
1431         cmd10->opcode = (cmd6.opcode == READ_6) ? READ_10 : WRITE_10;
1432         cmd10->byte2 = 0;
1433         scsi_ulto4b(scsi_3btoul(cmd6.addr), cmd10->addr);
1434         cmd10->reserved = 0;
1435         scsi_ulto2b(cmd6.length, cmd10->length);
1436         cmd10->control = cmd6.control;
1437         ccb->csio.cdb_len = sizeof(*cmd10);
1438
1439         /* Requeue request, unfreezing queue if necessary */
1440         frozen = (ccb->ccb_h.status & CAM_DEV_QFRZN) != 0;
1441         ccb->ccb_h.status = CAM_REQUEUE_REQ;
1442         xpt_action(ccb);
1443         if (frozen) {
1444                 cam_release_devq(ccb->ccb_h.path,
1445                                  /*relsim_flags*/0,
1446                                  /*reduction*/0,
1447                                  /*timeout*/0,
1448                                  /*getcount_only*/0);
1449         }
1450         return (ERESTART);
1451 }
1452
1453 static void
1454 dadone(struct cam_periph *periph, union ccb *done_ccb)
1455 {
1456         struct da_softc *softc;
1457         struct ccb_scsiio *csio;
1458         struct disk_info info;
1459
1460         softc = (struct da_softc *)periph->softc;
1461         csio = &done_ccb->csio;
1462         switch (csio->ccb_h.ccb_state & DA_CCB_TYPE_MASK) {
1463         case DA_CCB_BUFFER_IO:
1464         {
1465                 struct buf *bp;
1466                 struct bio *bio;
1467                 int mustsched = 0;
1468
1469                 bio = (struct bio *)done_ccb->ccb_h.ccb_bio;
1470                 bp = bio->bio_buf;
1471                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1472                         int error;
1473                         int sf;
1474                         
1475                         if ((csio->ccb_h.ccb_state & DA_CCB_RETRY_UA) != 0)
1476                                 sf = SF_RETRY_UA;
1477                         else
1478                                 sf = 0;
1479
1480                         error = daerror(done_ccb, CAM_RETRY_SELTO, sf);
1481                         if (error == ERESTART) {
1482                                 /*
1483                                  * A retry was scheuled, so
1484                                  * just return.
1485                                  */
1486                                 return;
1487                         }
1488                         if (error != 0) {
1489                                 if (error == ENXIO) {
1490                                         /*
1491                                          * Catastrophic error.  Mark our pack as
1492                                          * invalid.
1493                                          */
1494                                         /*
1495                                          * XXX See if this is really a media
1496                                          * XXX change first?
1497                                          */
1498                                         xpt_print(periph->path,
1499                                             "Invalidating pack\n");
1500                                         softc->flags |= DA_FLAG_PACK_INVALID;
1501                                 }
1502
1503                                 /*
1504                                  * Return all queued write I/O's with EIO
1505                                  * so the client can retry these I/Os in the
1506                                  * proper order should it attempt to recover.
1507                                  *
1508                                  * Leave read I/O's alone.
1509                                  */
1510                                 daflushbioq(&softc->bio_queue_wr, EIO);
1511                                 bp->b_error = error;
1512                                 bp->b_resid = bp->b_bcount;
1513                                 bp->b_flags |= B_ERROR;
1514                         } else {
1515                                 bp->b_resid = csio->resid;
1516                                 bp->b_error = 0;
1517                                 if (bp->b_resid != 0)
1518                                         bp->b_flags |= B_ERROR;
1519                         }
1520                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1521                                 cam_release_devq(done_ccb->ccb_h.path,
1522                                                  /*relsim_flags*/0,
1523                                                  /*reduction*/0,
1524                                                  /*timeout*/0,
1525                                                  /*getcount_only*/0);
1526                 } else {
1527                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1528                                 panic("REQ_CMP with QFRZN");
1529                         bp->b_resid = csio->resid;
1530                         if (csio->resid > 0)
1531                                 bp->b_flags |= B_ERROR;
1532                 }
1533
1534                 /*
1535                  * Block out any asyncronous callbacks
1536                  * while we touch the pending ccb list.
1537                  */
1538                 LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
1539                 if (bp->b_cmd == BUF_CMD_WRITE || bp->b_cmd == BUF_CMD_FLUSH) {
1540                         --softc->outstanding_cmds_wr;
1541                         if (softc->flags & DA_FLAG_WR_LIMIT) {
1542                                 softc->flags &= ~DA_FLAG_WR_LIMIT;
1543                                 mustsched = 1;
1544                         }
1545                 } else {
1546                         --softc->outstanding_cmds_rd;
1547                         if (softc->flags & DA_FLAG_RD_LIMIT) {
1548                                 softc->flags &= ~DA_FLAG_RD_LIMIT;
1549                                 mustsched = 1;
1550                         }
1551                 }
1552                 if (softc->outstanding_cmds_rd +
1553                     softc->outstanding_cmds_wr == 0) {
1554                         softc->flags |= DA_FLAG_WENT_IDLE;
1555                 }
1556
1557                 devstat_end_transaction_buf(&softc->device_stats, bp);
1558                 biodone(bio);
1559
1560                 if (mustsched)
1561                         xpt_schedule(periph, /*priority*/1);
1562
1563                 break;
1564         }
1565         case DA_CCB_PROBE:
1566         case DA_CCB_PROBE2:
1567         {
1568                 struct     scsi_read_capacity_data *rdcap;
1569                 struct     scsi_read_capacity_data_16 *rcaplong;
1570                 char       announce_buf[80];
1571
1572                 rdcap = NULL;
1573                 rcaplong = NULL;
1574                 if (softc->state == DA_STATE_PROBE)
1575                         rdcap =(struct scsi_read_capacity_data *)csio->data_ptr;
1576                 else
1577                         rcaplong = (struct scsi_read_capacity_data_16 *)
1578                                     csio->data_ptr;
1579
1580                 bzero(&info, sizeof(info));
1581                 info.d_type = DTYPE_SCSI;
1582                 info.d_serialno = xpt_path_serialno(periph->path);
1583                 
1584                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
1585                         struct disk_params *dp;
1586                         uint32_t block_size;
1587                         uint64_t maxsector;
1588
1589                         if (softc->state == DA_STATE_PROBE) {
1590                                 block_size = scsi_4btoul(rdcap->length);
1591                                 maxsector = scsi_4btoul(rdcap->addr);
1592
1593                                 /*
1594                                  * According to SBC-2, if the standard 10
1595                                  * byte READ CAPACITY command returns 2^32,
1596                                  * we should issue the 16 byte version of
1597                                  * the command, since the device in question
1598                                  * has more sectors than can be represented
1599                                  * with the short version of the command.
1600                                  */
1601                                 if (maxsector == 0xffffffff) {
1602                                         softc->state = DA_STATE_PROBE2;
1603                                         kfree(rdcap, M_SCSIDA);
1604                                         xpt_release_ccb(done_ccb);
1605                                         xpt_schedule(periph, /*priority*/5);
1606                                         return;
1607                                 }
1608                         } else {
1609                                 block_size = scsi_4btoul(rcaplong->length);
1610                                 maxsector = scsi_8btou64(rcaplong->addr);
1611                         }
1612                         dasetgeom(periph, block_size, maxsector);
1613                         dp = &softc->params;
1614                         ksnprintf(announce_buf, sizeof(announce_buf),
1615                                 "%juMB (%ju %u byte sectors: %dH %dS/T %dC)",
1616                                 (uintmax_t) (((uintmax_t)dp->secsize *
1617                                 dp->sectors) / (1024*1024)),
1618                                 (uintmax_t)dp->sectors,
1619                                 dp->secsize, dp->heads, dp->secs_per_track,
1620                                 dp->cylinders);
1621                         CAM_SIM_UNLOCK(periph->sim);
1622                         info.d_media_blksize = softc->params.secsize;
1623                         info.d_media_blocks = softc->params.sectors;
1624                         info.d_media_size = 0;
1625                         info.d_secpertrack = softc->params.secs_per_track;
1626                         info.d_nheads = softc->params.heads;
1627                         info.d_ncylinders = softc->params.cylinders;
1628                         info.d_secpercyl = softc->params.heads *
1629                                                 softc->params.secs_per_track;
1630                         info.d_serialno = xpt_path_serialno(periph->path);
1631                         disk_setdiskinfo(&softc->disk, &info);
1632                         CAM_SIM_LOCK(periph->sim);
1633                 } else {
1634                         int     error;
1635
1636                         announce_buf[0] = '\0';
1637
1638                         /*
1639                          * Retry any UNIT ATTENTION type errors.  They
1640                          * are expected at boot.
1641                          */
1642                         error = daerror(done_ccb, CAM_RETRY_SELTO,
1643                                         SF_RETRY_UA|SF_NO_PRINT);
1644                         if (error == ERESTART) {
1645                                 /*
1646                                  * A retry was scheuled, so
1647                                  * just return.
1648                                  */
1649                                 return;
1650                         } else if (error != 0) {
1651                                 struct scsi_sense_data *sense;
1652                                 int asc, ascq;
1653                                 int sense_key, error_code;
1654                                 int have_sense;
1655                                 cam_status status;
1656                                 struct ccb_getdev cgd;
1657
1658                                 /* Don't wedge this device's queue */
1659                                 status = done_ccb->ccb_h.status;
1660                                 if ((status & CAM_DEV_QFRZN) != 0)
1661                                         cam_release_devq(done_ccb->ccb_h.path,
1662                                                          /*relsim_flags*/0,
1663                                                          /*reduction*/0,
1664                                                          /*timeout*/0,
1665                                                          /*getcount_only*/0);
1666
1667
1668                                 xpt_setup_ccb(&cgd.ccb_h, 
1669                                               done_ccb->ccb_h.path,
1670                                               /* priority */ 1);
1671                                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
1672                                 xpt_action((union ccb *)&cgd);
1673
1674                                 if (((csio->ccb_h.flags & CAM_SENSE_PHYS) != 0)
1675                                  || ((csio->ccb_h.flags & CAM_SENSE_PTR) != 0)
1676                                  || ((status & CAM_AUTOSNS_VALID) == 0))
1677                                         have_sense = FALSE;
1678                                 else
1679                                         have_sense = TRUE;
1680
1681                                 if (have_sense) {
1682                                         sense = &csio->sense_data;
1683                                         scsi_extract_sense(sense, &error_code,
1684                                                            &sense_key, 
1685                                                            &asc, &ascq);
1686                                 }
1687                                 /*
1688                                  * Attach to anything that claims to be a
1689                                  * direct access or optical disk device,
1690                                  * as long as it doesn't return a "Logical
1691                                  * unit not supported" (0x25) error.
1692                                  */
1693                                 if ((have_sense) && (asc != 0x25)
1694                                  && (error_code == SSD_CURRENT_ERROR)) {
1695                                         const char *sense_key_desc;
1696                                         const char *asc_desc;
1697
1698                                         scsi_sense_desc(sense_key, asc, ascq,
1699                                                         &cgd.inq_data,
1700                                                         &sense_key_desc,
1701                                                         &asc_desc);
1702                                         ksnprintf(announce_buf,
1703                                             sizeof(announce_buf),
1704                                                 "Attempt to query device "
1705                                                 "size failed: %s, %s",
1706                                                 sense_key_desc,
1707                                                 asc_desc);
1708                                         info.d_media_blksize = 512;
1709                                         disk_setdiskinfo(&softc->disk, &info);
1710                                 } else {
1711                                         if (have_sense)
1712                                                 scsi_sense_print(
1713                                                         &done_ccb->csio);
1714                                         else {
1715                                                 xpt_print(periph->path,
1716                                                     "got CAM status %#x\n",
1717                                                     done_ccb->ccb_h.status);
1718                                         }
1719
1720                                         xpt_print(periph->path, "fatal error, "
1721                                             "failed to attach to device\n");
1722
1723                                         /*
1724                                          * Free up resources.
1725                                          */
1726                                         cam_periph_invalidate(periph);
1727                                 } 
1728                         }
1729                 }
1730                 kfree(csio->data_ptr, M_SCSIDA);
1731                 if (announce_buf[0] != '\0') {
1732                         xpt_announce_periph(periph, announce_buf);
1733                         /*
1734                          * Create our sysctl variables, now that we know
1735                          * we have successfully attached.
1736                          */
1737                         taskqueue_enqueue(taskqueue_thread[mycpuid],
1738                             &softc->sysctl_task);
1739                 }
1740                 softc->state = DA_STATE_NORMAL;
1741                 /*
1742                  * Since our peripheral may be invalidated by an error
1743                  * above or an external event, we must release our CCB
1744                  * before releasing the probe lock on the peripheral.
1745                  * The peripheral will only go away once the last lock
1746                  * is removed, and we need it around for the CCB release
1747                  * operation.
1748                  */
1749                 xpt_release_ccb(done_ccb);
1750                 cam_periph_unhold(periph, 0);
1751                 return;
1752         }
1753         case DA_CCB_WAITING:
1754         {
1755                 /* Caller will release the CCB */
1756                 wakeup(&done_ccb->ccb_h.cbfcnp);
1757                 return;
1758         }
1759         case DA_CCB_DUMP:
1760                 /* No-op.  We're polling */
1761                 return;
1762         default:
1763                 break;
1764         }
1765         xpt_release_ccb(done_ccb);
1766 }
1767
1768 static int
1769 daerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
1770 {
1771         struct da_softc   *softc;
1772         struct cam_periph *periph;
1773         int error;
1774
1775         periph = xpt_path_periph(ccb->ccb_h.path);
1776         softc = (struct da_softc *)periph->softc;
1777
1778         /*
1779          * Automatically detect devices that do not support
1780          * READ(6)/WRITE(6) and upgrade to using 10 byte cdbs.
1781          */
1782         error = 0;
1783         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INVALID) {
1784                 error = cmd6workaround(ccb);
1785         } else if (((ccb->ccb_h.status & CAM_STATUS_MASK) ==
1786                    CAM_SCSI_STATUS_ERROR)
1787          && (ccb->ccb_h.status & CAM_AUTOSNS_VALID)
1788          && (ccb->csio.scsi_status == SCSI_STATUS_CHECK_COND)
1789          && ((ccb->ccb_h.flags & CAM_SENSE_PHYS) == 0)
1790          && ((ccb->ccb_h.flags & CAM_SENSE_PTR) == 0)) {
1791                 int sense_key, error_code, asc, ascq;
1792
1793                 scsi_extract_sense(&ccb->csio.sense_data,
1794                                    &error_code, &sense_key, &asc, &ascq);
1795                 if (sense_key == SSD_KEY_ILLEGAL_REQUEST)
1796                         error = cmd6workaround(ccb);
1797         }
1798         if (error == ERESTART)
1799                 return (ERESTART);
1800
1801         /*
1802          * XXX
1803          * Until we have a better way of doing pack validation,
1804          * don't treat UAs as errors.
1805          */
1806         sense_flags |= SF_RETRY_UA;
1807         return(cam_periph_error(ccb, cam_flags, sense_flags,
1808                                 &softc->saved_ccb));
1809 }
1810
1811 static void
1812 daprevent(struct cam_periph *periph, int action)
1813 {
1814         struct  da_softc *softc;
1815         union   ccb *ccb;               
1816         int     error;
1817                 
1818         softc = (struct da_softc *)periph->softc;
1819
1820         if (((action == PR_ALLOW)
1821           && (softc->flags & DA_FLAG_PACK_LOCKED) == 0)
1822          || ((action == PR_PREVENT)
1823           && (softc->flags & DA_FLAG_PACK_LOCKED) != 0)) {
1824                 return;
1825         }
1826
1827         ccb = cam_periph_getccb(periph, /*priority*/1);
1828
1829         scsi_prevent(&ccb->csio,
1830                      /*retries*/1,
1831                      /*cbcfp*/dadone,
1832                      MSG_SIMPLE_Q_TAG,
1833                      action,
1834                      SSD_FULL_SIZE,
1835                      5000);
1836
1837         error = cam_periph_runccb(ccb, /*error_routine*/NULL, CAM_RETRY_SELTO,
1838                                   SF_RETRY_UA, &softc->device_stats);
1839
1840         if (error == 0) {
1841                 if (action == PR_ALLOW)
1842                         softc->flags &= ~DA_FLAG_PACK_LOCKED;
1843                 else
1844                         softc->flags |= DA_FLAG_PACK_LOCKED;
1845         }
1846
1847         xpt_release_ccb(ccb);
1848 }
1849
1850 /*
1851  * Check media on open, e.g. card reader devices which had no initial media.
1852  */
1853 static int
1854 dacheckmedia(struct cam_periph *periph)
1855 {
1856         struct disk_params *dp;
1857         struct da_softc *softc;
1858         struct disk_info info;
1859         int error;
1860
1861         softc = (struct da_softc *)periph->softc;
1862         dp = &softc->params;
1863
1864         error = dagetcapacity(periph);
1865
1866         /*
1867          * Only reprobe on initial open and if the media is removable.
1868          *
1869          * NOTE: If we setdiskinfo() it will take the device probe
1870          *       a bit of time to probe the slices and partitions,
1871          *       and mess up booting.  So avoid if nothing has changed.
1872          *       XXX
1873          */
1874         if (softc->flags & DA_FLAG_OPEN)
1875                 return (error);
1876         if ((softc->flags & DA_FLAG_PACK_REMOVABLE) == 0)
1877                 return (error);
1878
1879         bzero(&info, sizeof(info));
1880         info.d_type = DTYPE_SCSI;
1881         info.d_serialno = xpt_path_serialno(periph->path);
1882
1883         if (error == 0) {
1884                 CAM_SIM_UNLOCK(periph->sim);
1885                 info.d_media_blksize = softc->params.secsize;
1886                 info.d_media_blocks = softc->params.sectors;
1887                 info.d_media_size = 0;
1888                 info.d_secpertrack = softc->params.secs_per_track;
1889                 info.d_nheads = softc->params.heads;
1890                 info.d_ncylinders = softc->params.cylinders;
1891                 info.d_secpercyl = softc->params.heads *
1892                                         softc->params.secs_per_track;
1893                 info.d_serialno = xpt_path_serialno(periph->path);
1894                 if (info.d_media_blocks != softc->disk.d_info.d_media_blocks) {
1895                         kprintf("%s%d: open removable media: "
1896                                 "%juMB (%ju %u byte sectors: %dH %dS/T %dC)\n",
1897                                 periph->periph_name, periph->unit_number,
1898                                 (uintmax_t)(((uintmax_t)dp->secsize *
1899                                              dp->sectors) / (1024*1024)),
1900                                 (uintmax_t)dp->sectors, dp->secsize,
1901                                 dp->heads, dp->secs_per_track, dp->cylinders);
1902                         disk_setdiskinfo(&softc->disk, &info);
1903                 }
1904                 CAM_SIM_LOCK(periph->sim);
1905         } else {
1906                 kprintf("%s%d: open removable media: no media present\n",
1907                         periph->periph_name, periph->unit_number);
1908                 info.d_media_blksize = 512;
1909                 disk_setdiskinfo(&softc->disk, &info);
1910         }
1911         return (error);
1912 }
1913
1914 static int
1915 dagetcapacity(struct cam_periph *periph)
1916 {
1917         struct da_softc *softc;
1918         union ccb *ccb;
1919         struct scsi_read_capacity_data *rcap;
1920         struct scsi_read_capacity_data_16 *rcaplong;
1921         uint32_t block_len;
1922         uint64_t maxsector;
1923         int error;
1924  
1925         softc = (struct da_softc *)periph->softc;
1926         block_len = 0;
1927         maxsector = 0;
1928         error = 0;
1929  
1930         /* Do a read capacity */
1931         rcap = (struct scsi_read_capacity_data *)kmalloc(sizeof(*rcaplong),
1932                                                          M_SCSIDA, M_INTWAIT);
1933                 
1934         ccb = cam_periph_getccb(periph, /*priority*/1);
1935         scsi_read_capacity(&ccb->csio,
1936                            /*retries*/4,
1937                            /*cbfncp*/dadone,
1938                            MSG_SIMPLE_Q_TAG,
1939                            rcap,
1940                            SSD_FULL_SIZE,
1941                            /*timeout*/60000);
1942         ccb->ccb_h.ccb_bio = NULL;
1943  
1944         error = cam_periph_runccb(ccb, daerror,
1945                                   /*cam_flags*/CAM_RETRY_SELTO,
1946                                   /*sense_flags*/SF_RETRY_UA,
1947                                   &softc->device_stats);
1948  
1949         if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1950                 cam_release_devq(ccb->ccb_h.path,
1951                                  /*relsim_flags*/0,
1952                                  /*reduction*/0,
1953                                  /*timeout*/0,
1954                                  /*getcount_only*/0);
1955  
1956         if (error == 0) {
1957                 block_len = scsi_4btoul(rcap->length);
1958                 maxsector = scsi_4btoul(rcap->addr);
1959
1960                 if (maxsector != 0xffffffff)
1961                         goto done;
1962         } else
1963                 goto done;
1964  
1965         rcaplong = (struct scsi_read_capacity_data_16 *)rcap;
1966  
1967         scsi_read_capacity_16(&ccb->csio,
1968                               /*retries*/ 4,
1969                               /*cbfcnp*/ dadone,
1970                               /*tag_action*/ MSG_SIMPLE_Q_TAG,
1971                               /*lba*/ 0,
1972                               /*reladr*/ 0,
1973                               /*pmi*/ 0,
1974                               rcaplong,
1975                               /*sense_len*/ SSD_FULL_SIZE,
1976                               /*timeout*/ 60000);
1977         ccb->ccb_h.ccb_bio = NULL;
1978  
1979         error = cam_periph_runccb(ccb, daerror,
1980                                   /*cam_flags*/CAM_RETRY_SELTO,
1981                                   /*sense_flags*/SF_RETRY_UA,
1982                                   &softc->device_stats);
1983  
1984         if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1985                 cam_release_devq(ccb->ccb_h.path,
1986                                  /*relsim_flags*/0,
1987                                  /*reduction*/0,
1988                                  /*timeout*/0,
1989                                  /*getcount_only*/0);
1990  
1991         if (error == 0) {
1992                 block_len = scsi_4btoul(rcaplong->length);
1993                 maxsector = scsi_8btou64(rcaplong->addr);
1994         }
1995
1996 done:
1997
1998         if (error == 0)
1999                 dasetgeom(periph, block_len, maxsector);
2000  
2001         xpt_release_ccb(ccb);
2002  
2003         kfree(rcap, M_SCSIDA);
2004  
2005         return (error);
2006 }
2007
2008 static void
2009 dasetgeom(struct cam_periph *periph, uint32_t block_len, uint64_t maxsector)
2010 {
2011         struct ccb_calc_geometry ccg;
2012         struct da_softc *softc;
2013         struct disk_params *dp;
2014
2015         softc = (struct da_softc *)periph->softc;
2016
2017         dp = &softc->params;
2018         dp->secsize = block_len;
2019         dp->sectors = maxsector + 1;
2020         /*
2021          * Have the controller provide us with a geometry
2022          * for this disk.  The only time the geometry
2023          * matters is when we boot and the controller
2024          * is the only one knowledgeable enough to come
2025          * up with something that will make this a bootable
2026          * device.
2027          */
2028         xpt_setup_ccb(&ccg.ccb_h, periph->path, /*priority*/1);
2029         ccg.ccb_h.func_code = XPT_CALC_GEOMETRY;
2030         ccg.block_size = dp->secsize;
2031         ccg.volume_size = dp->sectors;
2032         ccg.heads = 0;
2033         ccg.secs_per_track = 0;
2034         ccg.cylinders = 0;
2035         xpt_action((union ccb*)&ccg);
2036         if ((ccg.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2037                 /*
2038                  * We don't know what went wrong here- but just pick
2039                  * a geometry so we don't have nasty things like divide
2040                  * by zero.
2041                  */
2042                 dp->heads = 255;
2043                 dp->secs_per_track = 255;
2044                 dp->cylinders = dp->sectors / (255 * 255);
2045                 if (dp->cylinders == 0) {
2046                         dp->cylinders = 1;
2047                 }
2048         } else {
2049                 dp->heads = ccg.heads;
2050                 dp->secs_per_track = ccg.secs_per_track;
2051                 dp->cylinders = ccg.cylinders;
2052         }
2053 }
2054
2055 static void
2056 dasendorderedtag(void *arg)
2057 {
2058         struct da_softc *softc = arg;
2059
2060         if (da_send_ordered) {
2061                 if ((softc->ordered_tag_count == 0)
2062                  && ((softc->flags & DA_FLAG_WENT_IDLE) == 0)) {
2063                         softc->flags |= DA_FLAG_NEED_OTAG;
2064                 }
2065                 if (softc->outstanding_cmds_rd || softc->outstanding_cmds_wr)
2066                         softc->flags &= ~DA_FLAG_WENT_IDLE;
2067
2068                 softc->ordered_tag_count = 0;
2069         }
2070         /* Queue us up again */
2071         callout_reset(&softc->sendordered_c,
2072             (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL,
2073             dasendorderedtag, softc);
2074 }
2075
2076 /*
2077  * Step through all DA peripheral drivers, and if the device is still open,
2078  * sync the disk cache to physical media.
2079  */
2080 static void
2081 dashutdown(void * arg, int howto)
2082 {
2083         struct cam_periph *periph;
2084         struct da_softc *softc;
2085
2086         TAILQ_FOREACH(periph, &dadriver.units, unit_links) {
2087                 union ccb ccb;
2088
2089                 cam_periph_lock(periph);
2090                 softc = (struct da_softc *)periph->softc;
2091
2092                 /*
2093                  * We only sync the cache if the drive is still open, and
2094                  * if the drive is capable of it..
2095                  */
2096                 if (((softc->flags & DA_FLAG_OPEN) == 0)
2097                  || (softc->quirks & DA_Q_NO_SYNC_CACHE)) {
2098                         cam_periph_unlock(periph);
2099                         continue;
2100                 }
2101
2102                 xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
2103
2104                 ccb.ccb_h.ccb_state = DA_CCB_DUMP;
2105                 scsi_synchronize_cache(&ccb.csio,
2106                                        /*retries*/1,
2107                                        /*cbfcnp*/dadone,
2108                                        MSG_SIMPLE_Q_TAG,
2109                                        /*begin_lba*/0, /* whole disk */
2110                                        /*lb_count*/0,
2111                                        SSD_FULL_SIZE,
2112                                        60 * 60 * 1000);
2113
2114                 xpt_polled_action(&ccb);
2115
2116                 if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2117                         if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
2118                              CAM_SCSI_STATUS_ERROR)
2119                          && (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
2120                                 int error_code, sense_key, asc, ascq;
2121
2122                                 scsi_extract_sense(&ccb.csio.sense_data,
2123                                                    &error_code, &sense_key,
2124                                                    &asc, &ascq);
2125
2126                                 if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
2127                                         scsi_sense_print(&ccb.csio);
2128                         } else {
2129                                 xpt_print(periph->path, "Synchronize "
2130                                     "cache failed, status == 0x%x, scsi status "
2131                                     "== 0x%x\n", ccb.ccb_h.status,
2132                                     ccb.csio.scsi_status);
2133                         }
2134                 }
2135
2136                 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
2137                         cam_release_devq(ccb.ccb_h.path,
2138                                          /*relsim_flags*/0,
2139                                          /*reduction*/0,
2140                                          /*timeout*/0,
2141                                          /*getcount_only*/0);
2142
2143                 cam_periph_unlock(periph);
2144         }
2145 }
2146
2147 #else /* !_KERNEL */
2148
2149 /*
2150  * XXX This is only left out of the kernel build to silence warnings.  If,
2151  * for some reason this function is used in the kernel, the ifdefs should
2152  * be moved so it is included both in the kernel and userland.
2153  */
2154 void
2155 scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries,
2156                  void (*cbfcnp)(struct cam_periph *, union ccb *),
2157                  u_int8_t tag_action, u_int8_t byte2, u_int16_t ileave,
2158                  u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
2159                  u_int32_t timeout)
2160 {
2161         struct scsi_format_unit *scsi_cmd;
2162
2163         scsi_cmd = (struct scsi_format_unit *)&csio->cdb_io.cdb_bytes;
2164         scsi_cmd->opcode = FORMAT_UNIT;
2165         scsi_cmd->byte2 = byte2;
2166         scsi_ulto2b(ileave, scsi_cmd->interleave);
2167
2168         cam_fill_csio(csio,
2169                       retries,
2170                       cbfcnp,
2171                       /*flags*/ (dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE,
2172                       tag_action,
2173                       data_ptr,
2174                       dxfer_len,
2175                       sense_len,
2176                       sizeof(*scsi_cmd),
2177                       timeout);
2178 }
2179
2180 #endif /* _KERNEL */