]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/cam/ata/ata_da.c
Remove all legacy ATA code parts, not used since options ATA_CAM enabled in
[FreeBSD/FreeBSD.git] / sys / cam / ata / ata_da.c
1 /*-
2  * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification, immediately at the beginning of the file.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include "opt_ada.h"
31 #include "opt_ata.h"
32
33 #include <sys/param.h>
34
35 #ifdef _KERNEL
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/bio.h>
39 #include <sys/sysctl.h>
40 #include <sys/taskqueue.h>
41 #include <sys/lock.h>
42 #include <sys/mutex.h>
43 #include <sys/conf.h>
44 #include <sys/devicestat.h>
45 #include <sys/eventhandler.h>
46 #include <sys/malloc.h>
47 #include <sys/cons.h>
48 #include <sys/reboot.h>
49 #include <geom/geom_disk.h>
50 #endif /* _KERNEL */
51
52 #ifndef _KERNEL
53 #include <stdio.h>
54 #include <string.h>
55 #endif /* _KERNEL */
56
57 #include <cam/cam.h>
58 #include <cam/cam_ccb.h>
59 #include <cam/cam_periph.h>
60 #include <cam/cam_xpt_periph.h>
61 #include <cam/cam_sim.h>
62
63 #include <cam/ata/ata_all.h>
64
65 #include <machine/md_var.h>     /* geometry translation */
66
67 #ifdef _KERNEL
68
69 #define ATA_MAX_28BIT_LBA               268435455UL
70
71 typedef enum {
72         ADA_STATE_RAHEAD,
73         ADA_STATE_WCACHE,
74         ADA_STATE_NORMAL
75 } ada_state;
76
77 typedef enum {
78         ADA_FLAG_PACK_INVALID   = 0x001,
79         ADA_FLAG_CAN_48BIT      = 0x002,
80         ADA_FLAG_CAN_FLUSHCACHE = 0x004,
81         ADA_FLAG_CAN_NCQ        = 0x008,
82         ADA_FLAG_CAN_DMA        = 0x010,
83         ADA_FLAG_NEED_OTAG      = 0x020,
84         ADA_FLAG_WENT_IDLE      = 0x040,
85         ADA_FLAG_CAN_TRIM       = 0x080,
86         ADA_FLAG_OPEN           = 0x100,
87         ADA_FLAG_SCTX_INIT      = 0x200,
88         ADA_FLAG_CAN_CFA        = 0x400,
89         ADA_FLAG_CAN_POWERMGT   = 0x800
90 } ada_flags;
91
92 typedef enum {
93         ADA_Q_NONE              = 0x00,
94         ADA_Q_4K                = 0x01,
95 } ada_quirks;
96
97 typedef enum {
98         ADA_CCB_RAHEAD          = 0x01,
99         ADA_CCB_WCACHE          = 0x02,
100         ADA_CCB_BUFFER_IO       = 0x03,
101         ADA_CCB_WAITING         = 0x04,
102         ADA_CCB_DUMP            = 0x05,
103         ADA_CCB_TRIM            = 0x06,
104         ADA_CCB_TYPE_MASK       = 0x0F,
105 } ada_ccb_state;
106
107 /* Offsets into our private area for storing information */
108 #define ccb_state       ppriv_field0
109 #define ccb_bp          ppriv_ptr1
110
111 struct disk_params {
112         u_int8_t  heads;
113         u_int8_t  secs_per_track;
114         u_int32_t cylinders;
115         u_int32_t secsize;      /* Number of bytes/logical sector */
116         u_int64_t sectors;      /* Total number sectors */
117 };
118
119 #define TRIM_MAX_BLOCKS 8
120 #define TRIM_MAX_RANGES (TRIM_MAX_BLOCKS * 64)
121 #define TRIM_MAX_BIOS   (TRIM_MAX_RANGES * 4)
122 struct trim_request {
123         uint8_t         data[TRIM_MAX_RANGES * 8];
124         struct bio      *bps[TRIM_MAX_BIOS];
125 };
126
127 struct ada_softc {
128         struct   bio_queue_head bio_queue;
129         struct   bio_queue_head trim_queue;
130         ada_state state;
131         ada_flags flags;        
132         ada_quirks quirks;
133         int      sort_io_queue;
134         int      ordered_tag_count;
135         int      outstanding_cmds;
136         int      trim_max_ranges;
137         int      trim_running;
138         int      read_ahead;
139         int      write_cache;
140 #ifdef ADA_TEST_FAILURE
141         int      force_read_error;
142         int      force_write_error;
143         int      periodic_read_error;
144         int      periodic_read_count;
145 #endif
146         struct   disk_params params;
147         struct   disk *disk;
148         struct task             sysctl_task;
149         struct sysctl_ctx_list  sysctl_ctx;
150         struct sysctl_oid       *sysctl_tree;
151         struct callout          sendordered_c;
152         struct trim_request     trim_req;
153 };
154
155 struct ada_quirk_entry {
156         struct scsi_inquiry_pattern inq_pat;
157         ada_quirks quirks;
158 };
159
160 static struct ada_quirk_entry ada_quirk_table[] =
161 {
162         {
163                 /* Hitachi Advanced Format (4k) drives */
164                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Hitachi H??????????E3*", "*" },
165                 /*quirks*/ADA_Q_4K
166         },
167         {
168                 /* Samsung Advanced Format (4k) drives */
169                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD155UI*", "*" },
170                 /*quirks*/ADA_Q_4K
171         },
172         {
173                 /* Samsung Advanced Format (4k) drives */
174                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD204UI*", "*" },
175                 /*quirks*/ADA_Q_4K
176         },
177         {
178                 /* Seagate Barracuda Green Advanced Format (4k) drives */
179                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DL*", "*" },
180                 /*quirks*/ADA_Q_4K
181         },
182         {
183                 /* Seagate Barracuda Advanced Format (4k) drives */
184                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???DM*", "*" },
185                 /*quirks*/ADA_Q_4K
186         },
187         {
188                 /* Seagate Barracuda Advanced Format (4k) drives */
189                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DM*", "*" },
190                 /*quirks*/ADA_Q_4K
191         },
192         {
193                 /* Seagate Momentus Advanced Format (4k) drives */
194                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500423AS*", "*" },
195                 /*quirks*/ADA_Q_4K
196         },
197         {
198                 /* Seagate Momentus Advanced Format (4k) drives */
199                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500424AS*", "*" },
200                 /*quirks*/ADA_Q_4K
201         },
202         {
203                 /* Seagate Momentus Advanced Format (4k) drives */
204                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640423AS*", "*" },
205                 /*quirks*/ADA_Q_4K
206         },
207         {
208                 /* Seagate Momentus Advanced Format (4k) drives */
209                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640424AS*", "*" },
210                 /*quirks*/ADA_Q_4K
211         },
212         {
213                 /* Seagate Momentus Advanced Format (4k) drives */
214                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750420AS*", "*" },
215                 /*quirks*/ADA_Q_4K
216         },
217         {
218                 /* Seagate Momentus Advanced Format (4k) drives */
219                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750422AS*", "*" },
220                 /*quirks*/ADA_Q_4K
221         },
222         {
223                 /* Seagate Momentus Advanced Format (4k) drives */
224                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750423AS*", "*" },
225                 /*quirks*/ADA_Q_4K
226         },
227         {
228                 /* Seagate Momentus Thin Advanced Format (4k) drives */
229                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???LT*", "*" },
230                 /*quirks*/ADA_Q_4K
231         },
232         {
233                 /* WDC Caviar Green Advanced Format (4k) drives */
234                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RS*", "*" },
235                 /*quirks*/ADA_Q_4K
236         },
237         {
238                 /* WDC Caviar Green Advanced Format (4k) drives */
239                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RX*", "*" },
240                 /*quirks*/ADA_Q_4K
241         },
242         {
243                 /* WDC Caviar Green Advanced Format (4k) drives */
244                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RS*", "*" },
245                 /*quirks*/ADA_Q_4K
246         },
247         {
248                 /* WDC Caviar Green Advanced Format (4k) drives */
249                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RX*", "*" },
250                 /*quirks*/ADA_Q_4K
251         },
252         {
253                 /* WDC Scorpio Black Advanced Format (4k) drives */
254                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PKT*", "*" },
255                 /*quirks*/ADA_Q_4K
256         },
257         {
258                 /* WDC Scorpio Black Advanced Format (4k) drives */
259                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PKT*", "*" },
260                 /*quirks*/ADA_Q_4K
261         },
262         {
263                 /* WDC Scorpio Blue Advanced Format (4k) drives */
264                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PVT*", "*" },
265                 /*quirks*/ADA_Q_4K
266         },
267         {
268                 /* WDC Scorpio Blue Advanced Format (4k) drives */
269                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PVT*", "*" },
270                 /*quirks*/ADA_Q_4K
271         },
272         {
273                 /*
274                  * Corsair Force 2 SSDs
275                  * 4k optimised & trim only works in 4k requests + 4k aligned
276                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
277                  * PR: 169974
278                  */
279                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair CSSD-F*", "*" },
280                 /*quirks*/ADA_Q_4K
281         },
282         {
283                 /*
284                  * Corsair Force 3 SSDs
285                  * 4k optimised & trim only works in 4k requests + 4k aligned
286                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
287                  * PR: 169974
288                  */
289                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Force 3*", "*" },
290                 /*quirks*/ADA_Q_4K
291         },
292         {
293                 /*
294                  * OCZ Agility 3 SSDs
295                  * 4k optimised & trim only works in 4k requests + 4k aligned
296                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
297                  * PR: 169974
298                  */
299                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY3*", "*" },
300                 /*quirks*/ADA_Q_4K
301         },
302         {
303                 /*
304                  * OCZ Vertex 2 SSDs (inc pro series)
305                  * 4k optimised & trim only works in 4k requests + 4k aligned
306                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
307                  * PR: 169974
308                  */
309                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ?VERTEX2*", "*" },
310                 /*quirks*/ADA_Q_4K
311         },
312         {
313                 /*
314                  * OCZ Vertex 3 SSDs
315                  * 4k optimised & trim only works in 4k requests + 4k aligned
316                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
317                  * PR: 169974
318                  */
319                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX3*", "*" },
320                 /*quirks*/ADA_Q_4K
321         },
322         {
323                 /*
324                  * SuperTalent TeraDrive CT SSDs
325                  * 4k optimised & trim only works in 4k requests + 4k aligned
326                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
327                  * PR: 169974
328                  */
329                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "FTM??CT25H*", "*" },
330                 /*quirks*/ADA_Q_4K
331         },
332         {
333                 /*
334                  * Crucial RealSSD C300 SSDs
335                  * 4k optimised
336                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
337                  * PR: 169974
338                  */
339                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "C300-CTFDDAC???MAG*",
340                 "*" }, /*quirks*/ADA_Q_4K
341         },
342         {
343                 /*
344                  * XceedIOPS SATA SSDs
345                  * 4k optimised
346                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
347                  * PR: 169974
348                  */
349                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SG9XCS2D*", "*" },
350                 /*quirks*/ADA_Q_4K
351         },
352         {
353                 /*
354                  * Intel 330 Series SSDs
355                  * 4k optimised & trim only works in 4k requests + 4k aligned
356                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
357                  * PR: 169974
358                  */
359                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2ct*", "*" },
360                 /*quirks*/ADA_Q_4K
361         },
362         {
363                 /*
364                  * OCZ Deneva R Series SSDs
365                  * 4k optimised & trim only works in 4k requests + 4k aligned
366                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
367                  * PR: 169974
368                  */
369                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "DENRSTE251M45*", "*" },
370                 /*quirks*/ADA_Q_4K
371         },
372         {
373                 /*
374                  * Kingston HyperX 3k SSDs
375                  * 4k optimised & trim only works in 4k requests + 4k aligned
376                  * Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
377                  * PR: 169974
378                  */
379                 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KINGSTON SH103S3*", "*" },
380                 /*quirks*/ADA_Q_4K
381         },
382         {
383                 /* Default */
384                 {
385                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
386                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
387                 },
388                 /*quirks*/0
389         },
390 };
391
392 static  disk_strategy_t adastrategy;
393 static  dumper_t        adadump;
394 static  periph_init_t   adainit;
395 static  void            adaasync(void *callback_arg, u_int32_t code,
396                                 struct cam_path *path, void *arg);
397 static  void            adasysctlinit(void *context, int pending);
398 static  periph_ctor_t   adaregister;
399 static  periph_dtor_t   adacleanup;
400 static  periph_start_t  adastart;
401 static  periph_oninv_t  adaoninvalidate;
402 static  void            adadone(struct cam_periph *periph,
403                                union ccb *done_ccb);
404 static  int             adaerror(union ccb *ccb, u_int32_t cam_flags,
405                                 u_int32_t sense_flags);
406 static void             adagetparams(struct cam_periph *periph,
407                                 struct ccb_getdev *cgd);
408 static timeout_t        adasendorderedtag;
409 static void             adashutdown(void *arg, int howto);
410 static void             adasuspend(void *arg);
411 static void             adaresume(void *arg);
412
413 #ifndef ADA_DEFAULT_LEGACY_ALIASES
414 #define ADA_DEFAULT_LEGACY_ALIASES      1
415 #endif
416
417 #ifndef ADA_DEFAULT_TIMEOUT
418 #define ADA_DEFAULT_TIMEOUT 30  /* Timeout in seconds */
419 #endif
420
421 #ifndef ADA_DEFAULT_RETRY
422 #define ADA_DEFAULT_RETRY       4
423 #endif
424
425 #ifndef ADA_DEFAULT_SEND_ORDERED
426 #define ADA_DEFAULT_SEND_ORDERED        1
427 #endif
428
429 #ifndef ADA_DEFAULT_SPINDOWN_SHUTDOWN
430 #define ADA_DEFAULT_SPINDOWN_SHUTDOWN   1
431 #endif
432
433 #ifndef ADA_DEFAULT_SPINDOWN_SUSPEND
434 #define ADA_DEFAULT_SPINDOWN_SUSPEND    1
435 #endif
436
437 #ifndef ADA_DEFAULT_READ_AHEAD
438 #define ADA_DEFAULT_READ_AHEAD  1
439 #endif
440
441 #ifndef ADA_DEFAULT_WRITE_CACHE
442 #define ADA_DEFAULT_WRITE_CACHE 1
443 #endif
444
445 #define ADA_RA  (softc->read_ahead >= 0 ? \
446                  softc->read_ahead : ada_read_ahead)
447 #define ADA_WC  (softc->write_cache >= 0 ? \
448                  softc->write_cache : ada_write_cache)
449 #define ADA_SIO (softc->sort_io_queue >= 0 ? \
450                  softc->sort_io_queue : cam_sort_io_queues)
451
452 /*
453  * Most platforms map firmware geometry to actual, but some don't.  If
454  * not overridden, default to nothing.
455  */
456 #ifndef ata_disk_firmware_geom_adjust
457 #define ata_disk_firmware_geom_adjust(disk)
458 #endif
459
460 static int ada_legacy_aliases = ADA_DEFAULT_LEGACY_ALIASES;
461 static int ada_retry_count = ADA_DEFAULT_RETRY;
462 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT;
463 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED;
464 static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN;
465 static int ada_spindown_suspend = ADA_DEFAULT_SPINDOWN_SUSPEND;
466 static int ada_read_ahead = ADA_DEFAULT_READ_AHEAD;
467 static int ada_write_cache = ADA_DEFAULT_WRITE_CACHE;
468
469 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0,
470             "CAM Direct Access Disk driver");
471 SYSCTL_INT(_kern_cam_ada, OID_AUTO, legacy_aliases, CTLFLAG_RW,
472            &ada_legacy_aliases, 0, "Create legacy-like device aliases");
473 TUNABLE_INT("kern.cam.ada.legacy_aliases", &ada_legacy_aliases);
474 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RW,
475            &ada_retry_count, 0, "Normal I/O retry count");
476 TUNABLE_INT("kern.cam.ada.retry_count", &ada_retry_count);
477 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RW,
478            &ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
479 TUNABLE_INT("kern.cam.ada.default_timeout", &ada_default_timeout);
480 SYSCTL_INT(_kern_cam_ada, OID_AUTO, send_ordered, CTLFLAG_RW,
481            &ada_send_ordered, 0, "Send Ordered Tags");
482 TUNABLE_INT("kern.cam.ada.send_ordered", &ada_send_ordered);
483 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RW,
484            &ada_spindown_shutdown, 0, "Spin down upon shutdown");
485 TUNABLE_INT("kern.cam.ada.spindown_shutdown", &ada_spindown_shutdown);
486 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_suspend, CTLFLAG_RW,
487            &ada_spindown_suspend, 0, "Spin down upon suspend");
488 TUNABLE_INT("kern.cam.ada.spindown_suspend", &ada_spindown_suspend);
489 SYSCTL_INT(_kern_cam_ada, OID_AUTO, read_ahead, CTLFLAG_RW,
490            &ada_read_ahead, 0, "Enable disk read-ahead");
491 TUNABLE_INT("kern.cam.ada.read_ahead", &ada_read_ahead);
492 SYSCTL_INT(_kern_cam_ada, OID_AUTO, write_cache, CTLFLAG_RW,
493            &ada_write_cache, 0, "Enable disk write cache");
494 TUNABLE_INT("kern.cam.ada.write_cache", &ada_write_cache);
495
496 /*
497  * ADA_ORDEREDTAG_INTERVAL determines how often, relative
498  * to the default timeout, we check to see whether an ordered
499  * tagged transaction is appropriate to prevent simple tag
500  * starvation.  Since we'd like to ensure that there is at least
501  * 1/2 of the timeout length left for a starved transaction to
502  * complete after we've sent an ordered tag, we must poll at least
503  * four times in every timeout period.  This takes care of the worst
504  * case where a starved transaction starts during an interval that
505  * meets the requirement "don't send an ordered tag" test so it takes
506  * us two intervals to determine that a tag must be sent.
507  */
508 #ifndef ADA_ORDEREDTAG_INTERVAL
509 #define ADA_ORDEREDTAG_INTERVAL 4
510 #endif
511
512 static struct periph_driver adadriver =
513 {
514         adainit, "ada",
515         TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0
516 };
517
518 PERIPHDRIVER_DECLARE(ada, adadriver);
519
520 static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers");
521
522 static int
523 adaopen(struct disk *dp)
524 {
525         struct cam_periph *periph;
526         struct ada_softc *softc;
527         int error;
528
529         periph = (struct cam_periph *)dp->d_drv1;
530         if (periph == NULL) {
531                 return (ENXIO); 
532         }
533
534         if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
535                 return(ENXIO);
536         }
537
538         cam_periph_lock(periph);
539         if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
540                 cam_periph_unlock(periph);
541                 cam_periph_release(periph);
542                 return (error);
543         }
544
545         softc = (struct ada_softc *)periph->softc;
546         softc->flags |= ADA_FLAG_OPEN;
547
548         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
549             ("adaopen\n"));
550
551         if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) {
552                 /* Invalidate our pack information. */
553                 softc->flags &= ~ADA_FLAG_PACK_INVALID;
554         }
555
556         cam_periph_unhold(periph);
557         cam_periph_unlock(periph);
558         return (0);
559 }
560
561 static int
562 adaclose(struct disk *dp)
563 {
564         struct  cam_periph *periph;
565         struct  ada_softc *softc;
566         union ccb *ccb;
567
568         periph = (struct cam_periph *)dp->d_drv1;
569         if (periph == NULL)
570                 return (ENXIO); 
571
572         cam_periph_lock(periph);
573         if (cam_periph_hold(periph, PRIBIO) != 0) {
574                 cam_periph_unlock(periph);
575                 cam_periph_release(periph);
576                 return (0);
577         }
578
579         softc = (struct ada_softc *)periph->softc;
580
581         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
582             ("adaclose\n"));
583
584         /* We only sync the cache if the drive is capable of it. */
585         if ((softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
586             (softc->flags & ADA_FLAG_PACK_INVALID) == 0) {
587
588                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
589                 cam_fill_ataio(&ccb->ataio,
590                                     1,
591                                     adadone,
592                                     CAM_DIR_NONE,
593                                     0,
594                                     NULL,
595                                     0,
596                                     ada_default_timeout*1000);
597
598                 if (softc->flags & ADA_FLAG_CAN_48BIT)
599                         ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
600                 else
601                         ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
602                 cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
603                     /*sense_flags*/0, softc->disk->d_devstat);
604
605                 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
606                         xpt_print(periph->path, "Synchronize cache failed\n");
607                 xpt_release_ccb(ccb);
608         }
609
610         softc->flags &= ~ADA_FLAG_OPEN;
611         cam_periph_unhold(periph);
612         cam_periph_unlock(periph);
613         cam_periph_release(periph);
614         return (0);     
615 }
616
617 static void
618 adaschedule(struct cam_periph *periph)
619 {
620         struct ada_softc *softc = (struct ada_softc *)periph->softc;
621         uint32_t prio;
622
623         /* Check if cam_periph_getccb() was called. */
624         prio = periph->immediate_priority;
625
626         /* Check if we have more work to do. */
627         if (bioq_first(&softc->bio_queue) ||
628             (!softc->trim_running && bioq_first(&softc->trim_queue))) {
629                 prio = CAM_PRIORITY_NORMAL;
630         }
631
632         /* Schedule CCB if any of above is true. */
633         if (prio != CAM_PRIORITY_NONE)
634                 xpt_schedule(periph, prio);
635 }
636
637 /*
638  * Actually translate the requested transfer into one the physical driver
639  * can understand.  The transfer is described by a buf and will include
640  * only one physical transfer.
641  */
642 static void
643 adastrategy(struct bio *bp)
644 {
645         struct cam_periph *periph;
646         struct ada_softc *softc;
647         
648         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
649         if (periph == NULL) {
650                 biofinish(bp, NULL, ENXIO);
651                 return;
652         }
653         softc = (struct ada_softc *)periph->softc;
654
655         cam_periph_lock(periph);
656
657         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastrategy(%p)\n", bp));
658
659         /*
660          * If the device has been made invalid, error out
661          */
662         if ((softc->flags & ADA_FLAG_PACK_INVALID)) {
663                 cam_periph_unlock(periph);
664                 biofinish(bp, NULL, ENXIO);
665                 return;
666         }
667         
668         /*
669          * Place it in the queue of disk activities for this disk
670          */
671         if (bp->bio_cmd == BIO_DELETE &&
672             (softc->flags & ADA_FLAG_CAN_TRIM)) {
673                 if (ADA_SIO)
674                     bioq_disksort(&softc->trim_queue, bp);
675                 else
676                     bioq_insert_tail(&softc->trim_queue, bp);
677         } else {
678                 if (ADA_SIO)
679                     bioq_disksort(&softc->bio_queue, bp);
680                 else
681                     bioq_insert_tail(&softc->bio_queue, bp);
682         }
683
684         /*
685          * Schedule ourselves for performing the work.
686          */
687         adaschedule(periph);
688         cam_periph_unlock(periph);
689
690         return;
691 }
692
693 static int
694 adadump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
695 {
696         struct      cam_periph *periph;
697         struct      ada_softc *softc;
698         u_int       secsize;
699         union       ccb ccb;
700         struct      disk *dp;
701         uint64_t    lba;
702         uint16_t    count;
703         int         error = 0;
704
705         dp = arg;
706         periph = dp->d_drv1;
707         if (periph == NULL)
708                 return (ENXIO);
709         softc = (struct ada_softc *)periph->softc;
710         cam_periph_lock(periph);
711         secsize = softc->params.secsize;
712         lba = offset / secsize;
713         count = length / secsize;
714         
715         if ((softc->flags & ADA_FLAG_PACK_INVALID) != 0) {
716                 cam_periph_unlock(periph);
717                 return (ENXIO);
718         }
719
720         if (length > 0) {
721                 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
722                 ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
723                 cam_fill_ataio(&ccb.ataio,
724                     0,
725                     adadone,
726                     CAM_DIR_OUT,
727                     0,
728                     (u_int8_t *) virtual,
729                     length,
730                     ada_default_timeout*1000);
731                 if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
732                     (lba + count >= ATA_MAX_28BIT_LBA ||
733                     count >= 256)) {
734                         ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48,
735                             0, lba, count);
736                 } else {
737                         ata_28bit_cmd(&ccb.ataio, ATA_WRITE_DMA,
738                             0, lba, count);
739                 }
740                 xpt_polled_action(&ccb);
741
742                 error = cam_periph_error(&ccb,
743                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
744                 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
745                         cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
746                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
747                 if (error != 0)
748                         printf("Aborting dump due to I/O error.\n");
749
750                 cam_periph_unlock(periph);
751                 return (error);
752         }
753
754         if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
755                 xpt_setup_ccb(&ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
756
757                 ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
758                 cam_fill_ataio(&ccb.ataio,
759                                     0,
760                                     adadone,
761                                     CAM_DIR_NONE,
762                                     0,
763                                     NULL,
764                                     0,
765                                     ada_default_timeout*1000);
766
767                 if (softc->flags & ADA_FLAG_CAN_48BIT)
768                         ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
769                 else
770                         ata_28bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
771                 xpt_polled_action(&ccb);
772
773                 error = cam_periph_error(&ccb,
774                     0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
775                 if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
776                         cam_release_devq(ccb.ccb_h.path, /*relsim_flags*/0,
777                             /*reduction*/0, /*timeout*/0, /*getcount_only*/0);
778                 if (error != 0)
779                         xpt_print(periph->path, "Synchronize cache failed\n");
780         }
781         cam_periph_unlock(periph);
782         return (error);
783 }
784
785 static void
786 adainit(void)
787 {
788         cam_status status;
789
790         /*
791          * Install a global async callback.  This callback will
792          * receive async callbacks like "new device found".
793          */
794         status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL);
795
796         if (status != CAM_REQ_CMP) {
797                 printf("ada: Failed to attach master async callback "
798                        "due to status 0x%x!\n", status);
799         } else if (ada_send_ordered) {
800
801                 /* Register our event handlers */
802                 if ((EVENTHANDLER_REGISTER(power_suspend, adasuspend,
803                                            NULL, EVENTHANDLER_PRI_LAST)) == NULL)
804                     printf("adainit: power event registration failed!\n");
805                 if ((EVENTHANDLER_REGISTER(power_resume, adaresume,
806                                            NULL, EVENTHANDLER_PRI_LAST)) == NULL)
807                     printf("adainit: power event registration failed!\n");
808                 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown,
809                                            NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
810                     printf("adainit: shutdown event registration failed!\n");
811         }
812 }
813
814 static void
815 adaoninvalidate(struct cam_periph *periph)
816 {
817         struct ada_softc *softc;
818
819         softc = (struct ada_softc *)periph->softc;
820
821         /*
822          * De-register any async callbacks.
823          */
824         xpt_register_async(0, adaasync, periph, periph->path);
825
826         softc->flags |= ADA_FLAG_PACK_INVALID;
827
828         /*
829          * Return all queued I/O with ENXIO.
830          * XXX Handle any transactions queued to the card
831          *     with XPT_ABORT_CCB.
832          */
833         bioq_flush(&softc->bio_queue, NULL, ENXIO);
834         bioq_flush(&softc->trim_queue, NULL, ENXIO);
835
836         disk_gone(softc->disk);
837         xpt_print(periph->path, "lost device\n");
838 }
839
840 static void
841 adacleanup(struct cam_periph *periph)
842 {
843         struct ada_softc *softc;
844
845         softc = (struct ada_softc *)periph->softc;
846
847         xpt_print(periph->path, "removing device entry\n");
848         cam_periph_unlock(periph);
849
850         /*
851          * If we can't free the sysctl tree, oh well...
852          */
853         if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0
854             && sysctl_ctx_free(&softc->sysctl_ctx) != 0) {
855                 xpt_print(periph->path, "can't remove sysctl context\n");
856         }
857
858         disk_destroy(softc->disk);
859         callout_drain(&softc->sendordered_c);
860         free(softc, M_DEVBUF);
861         cam_periph_lock(periph);
862 }
863
864 static void
865 adaasync(void *callback_arg, u_int32_t code,
866         struct cam_path *path, void *arg)
867 {
868         struct ccb_getdev cgd;
869         struct cam_periph *periph;
870         struct ada_softc *softc;
871
872         periph = (struct cam_periph *)callback_arg;
873         switch (code) {
874         case AC_FOUND_DEVICE:
875         {
876                 struct ccb_getdev *cgd;
877                 cam_status status;
878  
879                 cgd = (struct ccb_getdev *)arg;
880                 if (cgd == NULL)
881                         break;
882
883                 if (cgd->protocol != PROTO_ATA)
884                         break;
885
886                 /*
887                  * Allocate a peripheral instance for
888                  * this device and start the probe
889                  * process.
890                  */
891                 status = cam_periph_alloc(adaregister, adaoninvalidate,
892                                           adacleanup, adastart,
893                                           "ada", CAM_PERIPH_BIO,
894                                           cgd->ccb_h.path, adaasync,
895                                           AC_FOUND_DEVICE, cgd);
896
897                 if (status != CAM_REQ_CMP
898                  && status != CAM_REQ_INPROG)
899                         printf("adaasync: Unable to attach to new device "
900                                 "due to status 0x%x\n", status);
901                 break;
902         }
903         case AC_GETDEV_CHANGED:
904         {
905                 softc = (struct ada_softc *)periph->softc;
906                 xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
907                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
908                 xpt_action((union ccb *)&cgd);
909
910                 if ((cgd.ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
911                     (cgd.inq_flags & SID_DMA))
912                         softc->flags |= ADA_FLAG_CAN_DMA;
913                 else
914                         softc->flags &= ~ADA_FLAG_CAN_DMA;
915                 if ((cgd.ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
916                     (cgd.inq_flags & SID_DMA) && (cgd.inq_flags & SID_CmdQue))
917                         softc->flags |= ADA_FLAG_CAN_NCQ;
918                 else
919                         softc->flags &= ~ADA_FLAG_CAN_NCQ;
920                 if ((cgd.ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
921                     (cgd.inq_flags & SID_DMA))
922                         softc->flags |= ADA_FLAG_CAN_TRIM;
923                 else
924                         softc->flags &= ~ADA_FLAG_CAN_TRIM;
925
926                 cam_periph_async(periph, code, path, arg);
927                 break;
928         }
929         case AC_ADVINFO_CHANGED:
930         {
931                 uintptr_t buftype;
932
933                 buftype = (uintptr_t)arg;
934                 if (buftype == CDAI_TYPE_PHYS_PATH) {
935                         struct ada_softc *softc;
936
937                         softc = periph->softc;
938                         disk_attr_changed(softc->disk, "GEOM::physpath",
939                                           M_NOWAIT);
940                 }
941                 break;
942         }
943         case AC_SENT_BDR:
944         case AC_BUS_RESET:
945         {
946                 softc = (struct ada_softc *)periph->softc;
947                 cam_periph_async(periph, code, path, arg);
948                 if (softc->state != ADA_STATE_NORMAL)
949                         break;
950                 xpt_setup_ccb(&cgd.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
951                 cgd.ccb_h.func_code = XPT_GDEV_TYPE;
952                 xpt_action((union ccb *)&cgd);
953                 if (ADA_RA >= 0 &&
954                     cgd.ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD)
955                         softc->state = ADA_STATE_RAHEAD;
956                 else if (ADA_WC >= 0 &&
957                     cgd.ident_data.support.command1 & ATA_SUPPORT_WRITECACHE)
958                         softc->state = ADA_STATE_WCACHE;
959                 else
960                     break;
961                 cam_periph_acquire(periph);
962                 cam_freeze_devq_arg(periph->path,
963                     RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
964                 xpt_schedule(periph, CAM_PRIORITY_DEV);
965         }
966         default:
967                 cam_periph_async(periph, code, path, arg);
968                 break;
969         }
970 }
971
972 static void
973 adasysctlinit(void *context, int pending)
974 {
975         struct cam_periph *periph;
976         struct ada_softc *softc;
977         char tmpstr[80], tmpstr2[80];
978
979         periph = (struct cam_periph *)context;
980
981         /* periph was held for us when this task was enqueued */
982         if (periph->flags & CAM_PERIPH_INVALID) {
983                 cam_periph_release(periph);
984                 return;
985         }
986
987         softc = (struct ada_softc *)periph->softc;
988         snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d", periph->unit_number);
989         snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
990
991         sysctl_ctx_init(&softc->sysctl_ctx);
992         softc->flags |= ADA_FLAG_SCTX_INIT;
993         softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx,
994                 SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2,
995                 CTLFLAG_RD, 0, tmpstr);
996         if (softc->sysctl_tree == NULL) {
997                 printf("adasysctlinit: unable to allocate sysctl tree\n");
998                 cam_periph_release(periph);
999                 return;
1000         }
1001
1002         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1003                 OID_AUTO, "read_ahead", CTLFLAG_RW | CTLFLAG_MPSAFE,
1004                 &softc->read_ahead, 0, "Enable disk read ahead.");
1005         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1006                 OID_AUTO, "write_cache", CTLFLAG_RW | CTLFLAG_MPSAFE,
1007                 &softc->write_cache, 0, "Enable disk write cache.");
1008         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1009                 OID_AUTO, "sort_io_queue", CTLFLAG_RW | CTLFLAG_MPSAFE,
1010                 &softc->sort_io_queue, 0,
1011                 "Sort IO queue to try and optimise disk access patterns");
1012 #ifdef ADA_TEST_FAILURE
1013         /*
1014          * Add a 'door bell' sysctl which allows one to set it from userland
1015          * and cause something bad to happen.  For the moment, we only allow
1016          * whacking the next read or write.
1017          */
1018         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1019                 OID_AUTO, "force_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1020                 &softc->force_read_error, 0,
1021                 "Force a read error for the next N reads.");
1022         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1023                 OID_AUTO, "force_write_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1024                 &softc->force_write_error, 0,
1025                 "Force a write error for the next N writes.");
1026         SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1027                 OID_AUTO, "periodic_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1028                 &softc->periodic_read_error, 0,
1029                 "Force a read error every N reads (don't set too low).");
1030 #endif
1031         cam_periph_release(periph);
1032 }
1033
1034 static int
1035 adagetattr(struct bio *bp)
1036 {
1037         int ret;
1038         struct cam_periph *periph;
1039
1040         periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1041         if (periph == NULL)
1042                 return (ENXIO);
1043
1044         cam_periph_lock(periph);
1045         ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
1046             periph->path);
1047         cam_periph_unlock(periph);
1048         if (ret == 0)
1049                 bp->bio_completed = bp->bio_length;
1050         return ret;
1051 }
1052
1053 static cam_status
1054 adaregister(struct cam_periph *periph, void *arg)
1055 {
1056         struct ada_softc *softc;
1057         struct ccb_pathinq cpi;
1058         struct ccb_getdev *cgd;
1059         char   announce_buf[80], buf1[32];
1060         struct disk_params *dp;
1061         caddr_t match;
1062         u_int maxio;
1063         int legacy_id, quirks;
1064
1065         cgd = (struct ccb_getdev *)arg;
1066         if (cgd == NULL) {
1067                 printf("adaregister: no getdev CCB, can't register device\n");
1068                 return(CAM_REQ_CMP_ERR);
1069         }
1070
1071         softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF,
1072             M_NOWAIT|M_ZERO);
1073
1074         if (softc == NULL) {
1075                 printf("adaregister: Unable to probe new device. "
1076                     "Unable to allocate softc\n");
1077                 return(CAM_REQ_CMP_ERR);
1078         }
1079
1080         bioq_init(&softc->bio_queue);
1081         bioq_init(&softc->trim_queue);
1082
1083         if ((cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
1084             (cgd->inq_flags & SID_DMA))
1085                 softc->flags |= ADA_FLAG_CAN_DMA;
1086         if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48)
1087                 softc->flags |= ADA_FLAG_CAN_48BIT;
1088         if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
1089                 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
1090         if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
1091                 softc->flags |= ADA_FLAG_CAN_POWERMGT;
1092         if ((cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
1093             (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
1094                 softc->flags |= ADA_FLAG_CAN_NCQ;
1095         if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
1096             (cgd->inq_flags & SID_DMA)) {
1097                 softc->flags |= ADA_FLAG_CAN_TRIM;
1098                 softc->trim_max_ranges = TRIM_MAX_RANGES;
1099                 if (cgd->ident_data.max_dsm_blocks != 0) {
1100                         softc->trim_max_ranges =
1101                             min(cgd->ident_data.max_dsm_blocks * 64,
1102                                 softc->trim_max_ranges);
1103                 }
1104         }
1105         if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
1106                 softc->flags |= ADA_FLAG_CAN_CFA;
1107
1108         periph->softc = softc;
1109
1110         /*
1111          * See if this device has any quirks.
1112          */
1113         match = cam_quirkmatch((caddr_t)&cgd->ident_data,
1114                                (caddr_t)ada_quirk_table,
1115                                sizeof(ada_quirk_table)/sizeof(*ada_quirk_table),
1116                                sizeof(*ada_quirk_table), ata_identify_match);
1117         if (match != NULL)
1118                 softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
1119         else
1120                 softc->quirks = ADA_Q_NONE;
1121
1122         bzero(&cpi, sizeof(cpi));
1123         xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE);
1124         cpi.ccb_h.func_code = XPT_PATH_INQ;
1125         xpt_action((union ccb *)&cpi);
1126
1127         TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
1128
1129         /*
1130          * Register this media as a disk
1131          */
1132         (void)cam_periph_hold(periph, PRIBIO);
1133         mtx_unlock(periph->sim->mtx);
1134         snprintf(announce_buf, sizeof(announce_buf),
1135             "kern.cam.ada.%d.quirks", periph->unit_number);
1136         quirks = softc->quirks;
1137         TUNABLE_INT_FETCH(announce_buf, &quirks);
1138         softc->quirks = quirks;
1139         softc->read_ahead = -1;
1140         snprintf(announce_buf, sizeof(announce_buf),
1141             "kern.cam.ada.%d.read_ahead", periph->unit_number);
1142         TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead);
1143         softc->write_cache = -1;
1144         snprintf(announce_buf, sizeof(announce_buf),
1145             "kern.cam.ada.%d.write_cache", periph->unit_number);
1146         TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
1147         softc->sort_io_queue = -1;
1148         adagetparams(periph, cgd);
1149         softc->disk = disk_alloc();
1150         softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
1151                           periph->unit_number, softc->params.secsize,
1152                           DEVSTAT_ALL_SUPPORTED,
1153                           DEVSTAT_TYPE_DIRECT |
1154                           XPORT_DEVSTAT_TYPE(cpi.transport),
1155                           DEVSTAT_PRIORITY_DISK);
1156         softc->disk->d_open = adaopen;
1157         softc->disk->d_close = adaclose;
1158         softc->disk->d_strategy = adastrategy;
1159         softc->disk->d_getattr = adagetattr;
1160         softc->disk->d_dump = adadump;
1161         softc->disk->d_name = "ada";
1162         softc->disk->d_drv1 = periph;
1163         maxio = cpi.maxio;              /* Honor max I/O size of SIM */
1164         if (maxio == 0)
1165                 maxio = DFLTPHYS;       /* traditional default */
1166         else if (maxio > MAXPHYS)
1167                 maxio = MAXPHYS;        /* for safety */
1168         if (softc->flags & ADA_FLAG_CAN_48BIT)
1169                 maxio = min(maxio, 65536 * softc->params.secsize);
1170         else                                    /* 28bit ATA command limit */
1171                 maxio = min(maxio, 256 * softc->params.secsize);
1172         softc->disk->d_maxsize = maxio;
1173         softc->disk->d_unit = periph->unit_number;
1174         softc->disk->d_flags = 0;
1175         if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
1176                 softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
1177         if ((softc->flags & ADA_FLAG_CAN_TRIM) ||
1178             ((softc->flags & ADA_FLAG_CAN_CFA) &&
1179             !(softc->flags & ADA_FLAG_CAN_48BIT)))
1180                 softc->disk->d_flags |= DISKFLAG_CANDELETE;
1181         if ((cpi.hba_misc & PIM_UNMAPPED) != 0)
1182                 softc->disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
1183         strlcpy(softc->disk->d_descr, cgd->ident_data.model,
1184             MIN(sizeof(softc->disk->d_descr), sizeof(cgd->ident_data.model)));
1185         strlcpy(softc->disk->d_ident, cgd->ident_data.serial,
1186             MIN(sizeof(softc->disk->d_ident), sizeof(cgd->ident_data.serial)));
1187         softc->disk->d_hba_vendor = cpi.hba_vendor;
1188         softc->disk->d_hba_device = cpi.hba_device;
1189         softc->disk->d_hba_subvendor = cpi.hba_subvendor;
1190         softc->disk->d_hba_subdevice = cpi.hba_subdevice;
1191
1192         softc->disk->d_sectorsize = softc->params.secsize;
1193         softc->disk->d_mediasize = (off_t)softc->params.sectors *
1194             softc->params.secsize;
1195         if (ata_physical_sector_size(&cgd->ident_data) !=
1196             softc->params.secsize) {
1197                 softc->disk->d_stripesize =
1198                     ata_physical_sector_size(&cgd->ident_data);
1199                 softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
1200                     ata_logical_sector_offset(&cgd->ident_data)) %
1201                     softc->disk->d_stripesize;
1202         } else if (softc->quirks & ADA_Q_4K) {
1203                 softc->disk->d_stripesize = 4096;
1204                 softc->disk->d_stripeoffset = 0;
1205         }
1206         softc->disk->d_fwsectors = softc->params.secs_per_track;
1207         softc->disk->d_fwheads = softc->params.heads;
1208         ata_disk_firmware_geom_adjust(softc->disk);
1209
1210         if (ada_legacy_aliases) {
1211 #ifdef ATA_STATIC_ID
1212                 legacy_id = xpt_path_legacy_ata_id(periph->path);
1213 #else
1214                 legacy_id = softc->disk->d_unit;
1215 #endif
1216                 if (legacy_id >= 0) {
1217                         snprintf(announce_buf, sizeof(announce_buf),
1218                             "kern.devalias.%s%d",
1219                             softc->disk->d_name, softc->disk->d_unit);
1220                         snprintf(buf1, sizeof(buf1),
1221                             "ad%d", legacy_id);
1222                         setenv(announce_buf, buf1);
1223                 }
1224         } else
1225                 legacy_id = -1;
1226         disk_create(softc->disk, DISK_VERSION);
1227         mtx_lock(periph->sim->mtx);
1228         cam_periph_unhold(periph);
1229
1230         dp = &softc->params;
1231         snprintf(announce_buf, sizeof(announce_buf),
1232                 "%juMB (%ju %u byte sectors: %dH %dS/T %dC)",
1233                 (uintmax_t)(((uintmax_t)dp->secsize *
1234                 dp->sectors) / (1024*1024)),
1235                 (uintmax_t)dp->sectors,
1236                 dp->secsize, dp->heads,
1237                 dp->secs_per_track, dp->cylinders);
1238         xpt_announce_periph(periph, announce_buf);
1239         if (legacy_id >= 0)
1240                 printf("%s%d: Previously was known as ad%d\n",
1241                        periph->periph_name, periph->unit_number, legacy_id);
1242
1243         /*
1244          * Create our sysctl variables, now that we know
1245          * we have successfully attached.
1246          */
1247         cam_periph_acquire(periph);
1248         taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
1249
1250         /*
1251          * Add async callbacks for bus reset and
1252          * bus device reset calls.  I don't bother
1253          * checking if this fails as, in most cases,
1254          * the system will function just fine without
1255          * them and the only alternative would be to
1256          * not attach the device on failure.
1257          */
1258         xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
1259             AC_GETDEV_CHANGED | AC_ADVINFO_CHANGED,
1260             adaasync, periph, periph->path);
1261
1262         /*
1263          * Schedule a periodic event to occasionally send an
1264          * ordered tag to a device.
1265          */
1266         callout_init_mtx(&softc->sendordered_c, periph->sim->mtx, 0);
1267         callout_reset(&softc->sendordered_c,
1268             (ada_default_timeout * hz) / ADA_ORDEREDTAG_INTERVAL,
1269             adasendorderedtag, softc);
1270
1271         if (ADA_RA >= 0 &&
1272             cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD) {
1273                 softc->state = ADA_STATE_RAHEAD;
1274                 cam_periph_acquire(periph);
1275                 cam_freeze_devq_arg(periph->path,
1276                     RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
1277                 xpt_schedule(periph, CAM_PRIORITY_DEV);
1278         } else if (ADA_WC >= 0 &&
1279             cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) {
1280                 softc->state = ADA_STATE_WCACHE;
1281                 cam_periph_acquire(periph);
1282                 cam_freeze_devq_arg(periph->path,
1283                     RELSIM_RELEASE_RUNLEVEL, CAM_RL_DEV + 1);
1284                 xpt_schedule(periph, CAM_PRIORITY_DEV);
1285         } else
1286                 softc->state = ADA_STATE_NORMAL;
1287
1288         return(CAM_REQ_CMP);
1289 }
1290
1291 static void
1292 adastart(struct cam_periph *periph, union ccb *start_ccb)
1293 {
1294         struct ada_softc *softc = (struct ada_softc *)periph->softc;
1295         struct ccb_ataio *ataio = &start_ccb->ataio;
1296
1297         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
1298
1299         switch (softc->state) {
1300         case ADA_STATE_NORMAL:
1301         {
1302                 struct bio *bp;
1303                 u_int8_t tag_code;
1304
1305                 /* Execute immediate CCB if waiting. */
1306                 if (periph->immediate_priority <= periph->pinfo.priority) {
1307                         CAM_DEBUG(periph->path, CAM_DEBUG_SUBTRACE,
1308                                         ("queuing for immediate ccb\n"));
1309                         start_ccb->ccb_h.ccb_state = ADA_CCB_WAITING;
1310                         SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h,
1311                                           periph_links.sle);
1312                         periph->immediate_priority = CAM_PRIORITY_NONE;
1313                         wakeup(&periph->ccb_list);
1314                         /* Have more work to do, so ensure we stay scheduled */
1315                         adaschedule(periph);
1316                         break;
1317                 }
1318                 /* Run TRIM if not running yet. */
1319                 if (!softc->trim_running &&
1320                     (bp = bioq_first(&softc->trim_queue)) != 0) {
1321                         struct trim_request *req = &softc->trim_req;
1322                         struct bio *bp1;
1323                         uint64_t lastlba = (uint64_t)-1;
1324                         int bps = 0, c, lastcount = 0, off, ranges = 0;
1325
1326                         softc->trim_running = 1;
1327                         bzero(req, sizeof(*req));
1328                         bp1 = bp;
1329                         do {
1330                                 uint64_t lba = bp1->bio_pblkno;
1331                                 int count = bp1->bio_bcount /
1332                                     softc->params.secsize;
1333
1334                                 bioq_remove(&softc->trim_queue, bp1);
1335
1336                                 /* Try to extend the previous range. */
1337                                 if (lba == lastlba) {
1338                                         c = min(count, 0xffff - lastcount);
1339                                         lastcount += c;
1340                                         off = (ranges - 1) * 8;
1341                                         req->data[off + 6] = lastcount & 0xff;
1342                                         req->data[off + 7] =
1343                                             (lastcount >> 8) & 0xff;
1344                                         count -= c;
1345                                         lba += c;
1346                                 }
1347
1348                                 while (count > 0) {
1349                                         c = min(count, 0xffff);
1350                                         off = ranges * 8;
1351                                         req->data[off + 0] = lba & 0xff;
1352                                         req->data[off + 1] = (lba >> 8) & 0xff;
1353                                         req->data[off + 2] = (lba >> 16) & 0xff;
1354                                         req->data[off + 3] = (lba >> 24) & 0xff;
1355                                         req->data[off + 4] = (lba >> 32) & 0xff;
1356                                         req->data[off + 5] = (lba >> 40) & 0xff;
1357                                         req->data[off + 6] = c & 0xff;
1358                                         req->data[off + 7] = (c >> 8) & 0xff;
1359                                         lba += c;
1360                                         count -= c;
1361                                         lastcount = c;
1362                                         ranges++;
1363                                 }
1364                                 lastlba = lba;
1365                                 req->bps[bps++] = bp1;
1366                                 bp1 = bioq_first(&softc->trim_queue);
1367                                 if (bps >= TRIM_MAX_BIOS ||
1368                                     bp1 == NULL ||
1369                                     bp1->bio_bcount / softc->params.secsize >
1370                                     (softc->trim_max_ranges - ranges) * 0xffff)
1371                                         break;
1372                         } while (1);
1373                         cam_fill_ataio(ataio,
1374                             ada_retry_count,
1375                             adadone,
1376                             CAM_DIR_OUT,
1377                             0,
1378                             req->data,
1379                             ((ranges + 63) / 64) * 512,
1380                             ada_default_timeout * 1000);
1381                         ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
1382                             ATA_DSM_TRIM, 0, (ranges + 63) / 64);
1383                         start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
1384                         goto out;
1385                 }
1386                 /* Run regular command. */
1387                 bp = bioq_first(&softc->bio_queue);
1388                 if (bp == NULL) {
1389                         xpt_release_ccb(start_ccb);
1390                         break;
1391                 }
1392                 bioq_remove(&softc->bio_queue, bp);
1393
1394                 if ((bp->bio_flags & BIO_ORDERED) != 0
1395                  || (softc->flags & ADA_FLAG_NEED_OTAG) != 0) {
1396                         softc->flags &= ~ADA_FLAG_NEED_OTAG;
1397                         softc->ordered_tag_count++;
1398                         tag_code = 0;
1399                 } else {
1400                         tag_code = 1;
1401                 }
1402                 switch (bp->bio_cmd) {
1403                 case BIO_READ:
1404                 case BIO_WRITE:
1405                 {
1406                         uint64_t lba = bp->bio_pblkno;
1407                         uint16_t count = bp->bio_bcount / softc->params.secsize;
1408 #ifdef ADA_TEST_FAILURE
1409                         int fail = 0;
1410
1411                         /*
1412                          * Support the failure ioctls.  If the command is a
1413                          * read, and there are pending forced read errors, or
1414                          * if a write and pending write errors, then fail this
1415                          * operation with EIO.  This is useful for testing
1416                          * purposes.  Also, support having every Nth read fail.
1417                          *
1418                          * This is a rather blunt tool.
1419                          */
1420                         if (bp->bio_cmd == BIO_READ) {
1421                                 if (softc->force_read_error) {
1422                                         softc->force_read_error--;
1423                                         fail = 1;
1424                                 }
1425                                 if (softc->periodic_read_error > 0) {
1426                                         if (++softc->periodic_read_count >=
1427                                             softc->periodic_read_error) {
1428                                                 softc->periodic_read_count = 0;
1429                                                 fail = 1;
1430                                         }
1431                                 }
1432                         } else {
1433                                 if (softc->force_write_error) {
1434                                         softc->force_write_error--;
1435                                         fail = 1;
1436                                 }
1437                         }
1438                         if (fail) {
1439                                 bp->bio_error = EIO;
1440                                 bp->bio_flags |= BIO_ERROR;
1441                                 biodone(bp);
1442                                 xpt_release_ccb(start_ccb);
1443                                 adaschedule(periph);
1444                                 return;
1445                         }
1446 #endif
1447                         KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
1448                             round_page(bp->bio_bcount + bp->bio_ma_offset) /
1449                             PAGE_SIZE == bp->bio_ma_n,
1450                             ("Short bio %p", bp));
1451                         cam_fill_ataio(ataio,
1452                             ada_retry_count,
1453                             adadone,
1454                             (bp->bio_cmd == BIO_READ ? CAM_DIR_IN :
1455                                 CAM_DIR_OUT) | ((bp->bio_flags & BIO_UNMAPPED)
1456                                 != 0 ? CAM_DATA_BIO : 0),
1457                             tag_code,
1458                             ((bp->bio_flags & BIO_UNMAPPED) != 0) ? (void *)bp :
1459                                 bp->bio_data,
1460                             bp->bio_bcount,
1461                             ada_default_timeout*1000);
1462
1463                         if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
1464                                 if (bp->bio_cmd == BIO_READ) {
1465                                         ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
1466                                             lba, count);
1467                                 } else {
1468                                         ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
1469                                             lba, count);
1470                                 }
1471                         } else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
1472                             (lba + count >= ATA_MAX_28BIT_LBA ||
1473                             count > 256)) {
1474                                 if (softc->flags & ADA_FLAG_CAN_DMA) {
1475                                         if (bp->bio_cmd == BIO_READ) {
1476                                                 ata_48bit_cmd(ataio, ATA_READ_DMA48,
1477                                                     0, lba, count);
1478                                         } else {
1479                                                 ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
1480                                                     0, lba, count);
1481                                         }
1482                                 } else {
1483                                         if (bp->bio_cmd == BIO_READ) {
1484                                                 ata_48bit_cmd(ataio, ATA_READ_MUL48,
1485                                                     0, lba, count);
1486                                         } else {
1487                                                 ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
1488                                                     0, lba, count);
1489                                         }
1490                                 }
1491                         } else {
1492                                 if (count == 256)
1493                                         count = 0;
1494                                 if (softc->flags & ADA_FLAG_CAN_DMA) {
1495                                         if (bp->bio_cmd == BIO_READ) {
1496                                                 ata_28bit_cmd(ataio, ATA_READ_DMA,
1497                                                     0, lba, count);
1498                                         } else {
1499                                                 ata_28bit_cmd(ataio, ATA_WRITE_DMA,
1500                                                     0, lba, count);
1501                                         }
1502                                 } else {
1503                                         if (bp->bio_cmd == BIO_READ) {
1504                                                 ata_28bit_cmd(ataio, ATA_READ_MUL,
1505                                                     0, lba, count);
1506                                         } else {
1507                                                 ata_28bit_cmd(ataio, ATA_WRITE_MUL,
1508                                                     0, lba, count);
1509                                         }
1510                                 }
1511                         }
1512                         break;
1513                 }
1514                 case BIO_DELETE:
1515                 {
1516                         uint64_t lba = bp->bio_pblkno;
1517                         uint16_t count = bp->bio_bcount / softc->params.secsize;
1518
1519                         cam_fill_ataio(ataio,
1520                             ada_retry_count,
1521                             adadone,
1522                             CAM_DIR_NONE,
1523                             0,
1524                             NULL,
1525                             0,
1526                             ada_default_timeout*1000);
1527
1528                         if (count >= 256)
1529                                 count = 0;
1530                         ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
1531                         break;
1532                 }
1533                 case BIO_FLUSH:
1534                         cam_fill_ataio(ataio,
1535                             1,
1536                             adadone,
1537                             CAM_DIR_NONE,
1538                             0,
1539                             NULL,
1540                             0,
1541                             ada_default_timeout*1000);
1542
1543                         if (softc->flags & ADA_FLAG_CAN_48BIT)
1544                                 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1545                         else
1546                                 ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
1547                         break;
1548                 }
1549                 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
1550 out:
1551                 start_ccb->ccb_h.ccb_bp = bp;
1552                 softc->outstanding_cmds++;
1553                 xpt_action(start_ccb);
1554
1555                 /* May have more work to do, so ensure we stay scheduled */
1556                 adaschedule(periph);
1557                 break;
1558         }
1559         case ADA_STATE_RAHEAD:
1560         case ADA_STATE_WCACHE:
1561         {
1562                 if (softc->flags & ADA_FLAG_PACK_INVALID) {
1563                         softc->state = ADA_STATE_NORMAL;
1564                         xpt_release_ccb(start_ccb);
1565                         cam_release_devq(periph->path,
1566                             RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
1567                         adaschedule(periph);
1568                         cam_periph_release_locked(periph);
1569                         return;
1570                 }
1571
1572                 cam_fill_ataio(ataio,
1573                     1,
1574                     adadone,
1575                     CAM_DIR_NONE,
1576                     0,
1577                     NULL,
1578                     0,
1579                     ada_default_timeout*1000);
1580
1581                 if (softc->state == ADA_STATE_RAHEAD) {
1582                         ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_RA ?
1583                             ATA_SF_ENAB_RCACHE : ATA_SF_DIS_RCACHE, 0, 0);
1584                         start_ccb->ccb_h.ccb_state = ADA_CCB_RAHEAD;
1585                 } else {
1586                         ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_WC ?
1587                             ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0);
1588                         start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE;
1589                 }
1590                 xpt_action(start_ccb);
1591                 break;
1592         }
1593         }
1594 }
1595
1596 static void
1597 adadone(struct cam_periph *periph, union ccb *done_ccb)
1598 {
1599         struct ada_softc *softc;
1600         struct ccb_ataio *ataio;
1601         struct ccb_getdev *cgd;
1602
1603         softc = (struct ada_softc *)periph->softc;
1604         ataio = &done_ccb->ataio;
1605
1606         CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adadone\n"));
1607
1608         switch (ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) {
1609         case ADA_CCB_BUFFER_IO:
1610         case ADA_CCB_TRIM:
1611         {
1612                 struct bio *bp;
1613
1614                 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
1615                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1616                         int error;
1617                         
1618                         error = adaerror(done_ccb, 0, 0);
1619                         if (error == ERESTART) {
1620                                 /* A retry was scheduled, so just return. */
1621                                 return;
1622                         }
1623                         if (error != 0) {
1624                                 if (error == ENXIO &&
1625                                     (softc->flags & ADA_FLAG_PACK_INVALID) == 0) {
1626                                         /*
1627                                          * Catastrophic error.  Mark our pack as
1628                                          * invalid.
1629                                          */
1630                                         /*
1631                                          * XXX See if this is really a media
1632                                          * XXX change first?
1633                                          */
1634                                         xpt_print(periph->path,
1635                                             "Invalidating pack\n");
1636                                         softc->flags |= ADA_FLAG_PACK_INVALID;
1637                                 }
1638                                 bp->bio_error = error;
1639                                 bp->bio_resid = bp->bio_bcount;
1640                                 bp->bio_flags |= BIO_ERROR;
1641                         } else {
1642                                 bp->bio_resid = ataio->resid;
1643                                 bp->bio_error = 0;
1644                                 if (bp->bio_resid != 0)
1645                                         bp->bio_flags |= BIO_ERROR;
1646                         }
1647                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1648                                 cam_release_devq(done_ccb->ccb_h.path,
1649                                                  /*relsim_flags*/0,
1650                                                  /*reduction*/0,
1651                                                  /*timeout*/0,
1652                                                  /*getcount_only*/0);
1653                 } else {
1654                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
1655                                 panic("REQ_CMP with QFRZN");
1656                         bp->bio_resid = ataio->resid;
1657                         if (ataio->resid > 0)
1658                                 bp->bio_flags |= BIO_ERROR;
1659                 }
1660                 softc->outstanding_cmds--;
1661                 if (softc->outstanding_cmds == 0)
1662                         softc->flags |= ADA_FLAG_WENT_IDLE;
1663                 if ((ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK) ==
1664                     ADA_CCB_TRIM) {
1665                         struct trim_request *req =
1666                             (struct trim_request *)ataio->data_ptr;
1667                         int i;
1668
1669                         for (i = 1; i < TRIM_MAX_BIOS && req->bps[i]; i++) {
1670                                 struct bio *bp1 = req->bps[i];
1671                                 
1672                                 bp1->bio_resid = bp->bio_resid;
1673                                 bp1->bio_error = bp->bio_error;
1674                                 if (bp->bio_flags & BIO_ERROR)
1675                                         bp1->bio_flags |= BIO_ERROR;
1676                                 biodone(bp1);
1677                         }
1678                         softc->trim_running = 0;
1679                         biodone(bp);
1680                         adaschedule(periph);
1681                 } else
1682                         biodone(bp);
1683                 break;
1684         }
1685         case ADA_CCB_RAHEAD:
1686         {
1687                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1688                         if (adaerror(done_ccb, 0, 0) == ERESTART) {
1689                                 return;
1690                         } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1691                                 cam_release_devq(done_ccb->ccb_h.path,
1692                                     /*relsim_flags*/0,
1693                                     /*reduction*/0,
1694                                     /*timeout*/0,
1695                                     /*getcount_only*/0);
1696                         }
1697                 }
1698
1699                 /*
1700                  * Since our peripheral may be invalidated by an error
1701                  * above or an external event, we must release our CCB
1702                  * before releasing the reference on the peripheral.
1703                  * The peripheral will only go away once the last reference
1704                  * is removed, and we need it around for the CCB release
1705                  * operation.
1706                  */
1707                 cgd = (struct ccb_getdev *)done_ccb;
1708                 xpt_setup_ccb(&cgd->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1709                 cgd->ccb_h.func_code = XPT_GDEV_TYPE;
1710                 xpt_action((union ccb *)cgd);
1711                 if (ADA_WC >= 0 &&
1712                     cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE) {
1713                         softc->state = ADA_STATE_WCACHE;
1714                         xpt_release_ccb(done_ccb);
1715                         xpt_schedule(periph, CAM_PRIORITY_DEV);
1716                         return;
1717                 }
1718                 softc->state = ADA_STATE_NORMAL;
1719                 xpt_release_ccb(done_ccb);
1720                 cam_release_devq(periph->path,
1721                     RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
1722                 adaschedule(periph);
1723                 cam_periph_release_locked(periph);
1724                 return;
1725         }
1726         case ADA_CCB_WCACHE:
1727         {
1728                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
1729                         if (adaerror(done_ccb, 0, 0) == ERESTART) {
1730                                 return;
1731                         } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
1732                                 cam_release_devq(done_ccb->ccb_h.path,
1733                                     /*relsim_flags*/0,
1734                                     /*reduction*/0,
1735                                     /*timeout*/0,
1736                                     /*getcount_only*/0);
1737                         }
1738                 }
1739
1740                 softc->state = ADA_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 reference on the peripheral.
1745                  * The peripheral will only go away once the last reference
1746                  * is removed, and we need it around for the CCB release
1747                  * operation.
1748                  */
1749                 xpt_release_ccb(done_ccb);
1750                 cam_release_devq(periph->path,
1751                     RELSIM_RELEASE_RUNLEVEL, 0, CAM_RL_DEV + 1, FALSE);
1752                 adaschedule(periph);
1753                 cam_periph_release_locked(periph);
1754                 return;
1755         }
1756         case ADA_CCB_WAITING:
1757         {
1758                 /* Caller will release the CCB */
1759                 wakeup(&done_ccb->ccb_h.cbfcnp);
1760                 return;
1761         }
1762         case ADA_CCB_DUMP:
1763                 /* No-op.  We're polling */
1764                 return;
1765         default:
1766                 break;
1767         }
1768         xpt_release_ccb(done_ccb);
1769 }
1770
1771 static int
1772 adaerror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags)
1773 {
1774
1775         return(cam_periph_error(ccb, cam_flags, sense_flags, NULL));
1776 }
1777
1778 static void
1779 adagetparams(struct cam_periph *periph, struct ccb_getdev *cgd)
1780 {
1781         struct ada_softc *softc = (struct ada_softc *)periph->softc;
1782         struct disk_params *dp = &softc->params;
1783         u_int64_t lbasize48;
1784         u_int32_t lbasize;
1785
1786         dp->secsize = ata_logical_sector_size(&cgd->ident_data);
1787         if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
1788                 cgd->ident_data.current_heads && cgd->ident_data.current_sectors) {
1789                 dp->heads = cgd->ident_data.current_heads;
1790                 dp->secs_per_track = cgd->ident_data.current_sectors;
1791                 dp->cylinders = cgd->ident_data.cylinders;
1792                 dp->sectors = (u_int32_t)cgd->ident_data.current_size_1 |
1793                           ((u_int32_t)cgd->ident_data.current_size_2 << 16);
1794         } else {
1795                 dp->heads = cgd->ident_data.heads;
1796                 dp->secs_per_track = cgd->ident_data.sectors;
1797                 dp->cylinders = cgd->ident_data.cylinders;
1798                 dp->sectors = cgd->ident_data.cylinders * dp->heads * dp->secs_per_track;  
1799         }
1800         lbasize = (u_int32_t)cgd->ident_data.lba_size_1 |
1801                   ((u_int32_t)cgd->ident_data.lba_size_2 << 16);
1802
1803         /* use the 28bit LBA size if valid or bigger than the CHS mapping */
1804         if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
1805                 dp->sectors = lbasize;
1806
1807         /* use the 48bit LBA size if valid */
1808         lbasize48 = ((u_int64_t)cgd->ident_data.lba_size48_1) |
1809                     ((u_int64_t)cgd->ident_data.lba_size48_2 << 16) |
1810                     ((u_int64_t)cgd->ident_data.lba_size48_3 << 32) |
1811                     ((u_int64_t)cgd->ident_data.lba_size48_4 << 48);
1812         if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) &&
1813             lbasize48 > ATA_MAX_28BIT_LBA)
1814                 dp->sectors = lbasize48;
1815 }
1816
1817 static void
1818 adasendorderedtag(void *arg)
1819 {
1820         struct ada_softc *softc = arg;
1821
1822         if (ada_send_ordered) {
1823                 if ((softc->ordered_tag_count == 0) 
1824                  && ((softc->flags & ADA_FLAG_WENT_IDLE) == 0)) {
1825                         softc->flags |= ADA_FLAG_NEED_OTAG;
1826                 }
1827                 if (softc->outstanding_cmds > 0)
1828                         softc->flags &= ~ADA_FLAG_WENT_IDLE;
1829
1830                 softc->ordered_tag_count = 0;
1831         }
1832         /* Queue us up again */
1833         callout_reset(&softc->sendordered_c,
1834             (ada_default_timeout * hz) / ADA_ORDEREDTAG_INTERVAL,
1835             adasendorderedtag, softc);
1836 }
1837
1838 /*
1839  * Step through all ADA peripheral drivers, and if the device is still open,
1840  * sync the disk cache to physical media.
1841  */
1842 static void
1843 adaflush(void)
1844 {
1845         struct cam_periph *periph;
1846         struct ada_softc *softc;
1847         union ccb *ccb;
1848         int error;
1849
1850         CAM_PERIPH_FOREACH(periph, &adadriver) {
1851                 /* If we paniced with lock held - not recurse here. */
1852                 if (cam_periph_owned(periph))
1853                         continue;
1854                 cam_periph_lock(periph);
1855                 softc = (struct ada_softc *)periph->softc;
1856                 /*
1857                  * We only sync the cache if the drive is still open, and
1858                  * if the drive is capable of it..
1859                  */
1860                 if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
1861                     (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
1862                         cam_periph_unlock(periph);
1863                         continue;
1864                 }
1865
1866                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1867                 cam_fill_ataio(&ccb->ataio,
1868                                     0,
1869                                     adadone,
1870                                     CAM_DIR_NONE,
1871                                     0,
1872                                     NULL,
1873                                     0,
1874                                     ada_default_timeout*1000);
1875                 if (softc->flags & ADA_FLAG_CAN_48BIT)
1876                         ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1877                 else
1878                         ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
1879
1880                 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
1881                     /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
1882                     softc->disk->d_devstat);
1883                 if (error != 0)
1884                         xpt_print(periph->path, "Synchronize cache failed\n");
1885                 xpt_release_ccb(ccb);
1886                 cam_periph_unlock(periph);
1887         }
1888 }
1889
1890 static void
1891 adaspindown(uint8_t cmd, int flags)
1892 {
1893         struct cam_periph *periph;
1894         struct ada_softc *softc;
1895         union ccb *ccb;
1896         int error;
1897
1898         CAM_PERIPH_FOREACH(periph, &adadriver) {
1899                 /* If we paniced with lock held - not recurse here. */
1900                 if (cam_periph_owned(periph))
1901                         continue;
1902                 cam_periph_lock(periph);
1903                 softc = (struct ada_softc *)periph->softc;
1904                 /*
1905                  * We only spin-down the drive if it is capable of it..
1906                  */
1907                 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
1908                         cam_periph_unlock(periph);
1909                         continue;
1910                 }
1911
1912                 if (bootverbose)
1913                         xpt_print(periph->path, "spin-down\n");
1914
1915                 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1916                 cam_fill_ataio(&ccb->ataio,
1917                                     0,
1918                                     adadone,
1919                                     CAM_DIR_NONE | flags,
1920                                     0,
1921                                     NULL,
1922                                     0,
1923                                     ada_default_timeout*1000);
1924                 ata_28bit_cmd(&ccb->ataio, cmd, 0, 0, 0);
1925
1926                 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
1927                     /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
1928                     softc->disk->d_devstat);
1929                 if (error != 0)
1930                         xpt_print(periph->path, "Spin-down disk failed\n");
1931                 xpt_release_ccb(ccb);
1932                 cam_periph_unlock(periph);
1933         }
1934 }
1935
1936 static void
1937 adashutdown(void *arg, int howto)
1938 {
1939
1940         adaflush();
1941         if (ada_spindown_shutdown != 0 &&
1942             (howto & (RB_HALT | RB_POWEROFF)) != 0)
1943                 adaspindown(ATA_STANDBY_IMMEDIATE, 0);
1944 }
1945
1946 static void
1947 adasuspend(void *arg)
1948 {
1949
1950         adaflush();
1951         if (ada_spindown_suspend != 0)
1952                 adaspindown(ATA_SLEEP, CAM_DEV_QFREEZE);
1953 }
1954
1955 static void
1956 adaresume(void *arg)
1957 {
1958         struct cam_periph *periph;
1959         struct ada_softc *softc;
1960
1961         if (ada_spindown_suspend == 0)
1962                 return;
1963
1964         CAM_PERIPH_FOREACH(periph, &adadriver) {
1965                 cam_periph_lock(periph);
1966                 softc = (struct ada_softc *)periph->softc;
1967                 /*
1968                  * We only spin-down the drive if it is capable of it..
1969                  */
1970                 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
1971                         cam_periph_unlock(periph);
1972                         continue;
1973                 }
1974
1975                 if (bootverbose)
1976                         xpt_print(periph->path, "resume\n");
1977
1978                 /*
1979                  * Drop freeze taken due to CAM_DEV_QFREEZE flag set on
1980                  * sleep request.
1981                  */
1982                 cam_release_devq(periph->path,
1983                          /*relsim_flags*/0,
1984                          /*openings*/0,
1985                          /*timeout*/0,
1986                          /*getcount_only*/0);
1987                 
1988                 cam_periph_unlock(periph);
1989         }
1990 }
1991
1992 #endif /* _KERNEL */