1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
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. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "opt_ada.h"
30
31 #include <sys/param.h>
32
33 #ifdef _KERNEL
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/bio.h>
37 #include <sys/sysctl.h>
38 #include <sys/taskqueue.h>
39 #include <sys/lock.h>
40 #include <sys/mutex.h>
41 #include <sys/conf.h>
42 #include <sys/devicestat.h>
43 #include <sys/eventhandler.h>
44 #include <sys/malloc.h>
45 #include <sys/endian.h>
46 #include <sys/cons.h>
47 #include <sys/power.h>
48 #include <sys/proc.h>
49 #include <sys/reboot.h>
50 #include <sys/sbuf.h>
51 #include <geom/geom.h>
52 #include <geom/geom_disk.h>
53 #endif /* _KERNEL */
54
55 #ifndef _KERNEL
56 #include <stdio.h>
57 #include <string.h>
58 #endif /* _KERNEL */
59
60 #include <cam/cam.h>
61 #include <cam/cam_ccb.h>
62 #include <cam/cam_periph.h>
63 #include <cam/cam_xpt_periph.h>
64 #include <cam/scsi/scsi_all.h>
65 #include <cam/scsi/scsi_da.h>
66 #include <cam/cam_sim.h>
67 #include <cam/cam_iosched.h>
68
69 #include <cam/ata/ata_all.h>
70
71 /* SDT Probes */
72 SDT_PROBE_DEFINE3(cam, , ada, error, "union ccb *", "uint32_t", "uint32_t");
73 SDT_PROBE_DEFINE2(cam, , ada, recovery, "union ccb *", "int");
74
75 #ifdef _KERNEL
76
77 #define ATA_MAX_28BIT_LBA 268435455UL
78
79 extern int iosched_debug;
80
81 typedef enum {
82 ADA_STATE_RAHEAD,
83 ADA_STATE_WCACHE,
84 ADA_STATE_LOGDIR,
85 ADA_STATE_IDDIR,
86 ADA_STATE_SUP_CAP,
87 ADA_STATE_ZONE,
88 ADA_STATE_NORMAL
89 } ada_state;
90
91 typedef enum {
92 ADA_FLAG_CAN_48BIT = 0x00000002,
93 ADA_FLAG_CAN_FLUSHCACHE = 0x00000004,
94 ADA_FLAG_CAN_NCQ = 0x00000008,
95 ADA_FLAG_CAN_DMA = 0x00000010,
96 ADA_FLAG_NEED_OTAG = 0x00000020,
97 ADA_FLAG_WAS_OTAG = 0x00000040,
98 ADA_FLAG_CAN_TRIM = 0x00000080,
99 ADA_FLAG_OPEN = 0x00000100,
100 ADA_FLAG_SCTX_INIT = 0x00000200,
101 ADA_FLAG_CAN_CFA = 0x00000400,
102 ADA_FLAG_CAN_POWERMGT = 0x00000800,
103 ADA_FLAG_CAN_DMA48 = 0x00001000,
104 ADA_FLAG_CAN_LOG = 0x00002000,
105 ADA_FLAG_CAN_IDLOG = 0x00004000,
106 ADA_FLAG_CAN_SUPCAP = 0x00008000,
107 ADA_FLAG_CAN_ZONE = 0x00010000,
108 ADA_FLAG_CAN_WCACHE = 0x00020000,
109 ADA_FLAG_CAN_RAHEAD = 0x00040000,
110 ADA_FLAG_PROBED = 0x00080000,
111 ADA_FLAG_ANNOUNCED = 0x00100000,
112 ADA_FLAG_DIRTY = 0x00200000,
113 ADA_FLAG_CAN_NCQ_TRIM = 0x00400000, /* CAN_TRIM also set */
114 ADA_FLAG_PIM_ATA_EXT = 0x00800000,
115 ADA_FLAG_UNMAPPEDIO = 0x01000000,
116 ADA_FLAG_ROTATING = 0x02000000
117 } ada_flags;
118 #define ADA_FLAG_STRING \
119 "\020" \
120 "\002CAN_48BIT" \
121 "\003CAN_FLUSHCACHE" \
122 "\004CAN_NCQ" \
123 "\005CAN_DMA" \
124 "\006NEED_OTAG" \
125 "\007WAS_OTAG" \
126 "\010CAN_TRIM" \
127 "\011OPEN" \
128 "\012SCTX_INIT" \
129 "\013CAN_CFA" \
130 "\014CAN_POWERMGT" \
131 "\015CAN_DMA48" \
132 "\016CAN_LOG" \
133 "\017CAN_IDLOG" \
134 "\020CAN_SUPCAP" \
135 "\021CAN_ZONE" \
136 "\022CAN_WCACHE" \
137 "\023CAN_RAHEAD" \
138 "\024PROBED" \
139 "\025ANNOUNCED" \
140 "\026DIRTY" \
141 "\027CAN_NCQ_TRIM" \
142 "\030PIM_ATA_EXT" \
143 "\031UNMAPPEDIO" \
144 "\032ROTATING"
145
146 typedef enum {
147 ADA_Q_NONE = 0x00,
148 ADA_Q_4K = 0x01,
149 ADA_Q_NCQ_TRIM_BROKEN = 0x02,
150 ADA_Q_LOG_BROKEN = 0x04,
151 ADA_Q_SMR_DM = 0x08,
152 ADA_Q_NO_TRIM = 0x10,
153 ADA_Q_128KB = 0x20
154 } ada_quirks;
155
156 #define ADA_Q_BIT_STRING \
157 "\020" \
158 "\0014K" \
159 "\002NCQ_TRIM_BROKEN" \
160 "\003LOG_BROKEN" \
161 "\004SMR_DM" \
162 "\005NO_TRIM" \
163 "\006128KB"
164
165 typedef enum {
166 ADA_CCB_RAHEAD = 0x01,
167 ADA_CCB_WCACHE = 0x02,
168 ADA_CCB_BUFFER_IO = 0x03,
169 ADA_CCB_DUMP = 0x05,
170 ADA_CCB_TRIM = 0x06,
171 ADA_CCB_LOGDIR = 0x07,
172 ADA_CCB_IDDIR = 0x08,
173 ADA_CCB_SUP_CAP = 0x09,
174 ADA_CCB_ZONE = 0x0a,
175 ADA_CCB_TYPE_MASK = 0x0F,
176 } ada_ccb_state;
177
178 typedef enum {
179 ADA_ZONE_NONE = 0x00,
180 ADA_ZONE_DRIVE_MANAGED = 0x01,
181 ADA_ZONE_HOST_AWARE = 0x02,
182 ADA_ZONE_HOST_MANAGED = 0x03
183 } ada_zone_mode;
184
185 typedef enum {
186 ADA_ZONE_FLAG_RZ_SUP = 0x0001,
187 ADA_ZONE_FLAG_OPEN_SUP = 0x0002,
188 ADA_ZONE_FLAG_CLOSE_SUP = 0x0004,
189 ADA_ZONE_FLAG_FINISH_SUP = 0x0008,
190 ADA_ZONE_FLAG_RWP_SUP = 0x0010,
191 ADA_ZONE_FLAG_SUP_MASK = (ADA_ZONE_FLAG_RZ_SUP |
192 ADA_ZONE_FLAG_OPEN_SUP |
193 ADA_ZONE_FLAG_CLOSE_SUP |
194 ADA_ZONE_FLAG_FINISH_SUP |
195 ADA_ZONE_FLAG_RWP_SUP),
196 ADA_ZONE_FLAG_URSWRZ = 0x0020,
197 ADA_ZONE_FLAG_OPT_SEQ_SET = 0x0040,
198 ADA_ZONE_FLAG_OPT_NONSEQ_SET = 0x0080,
199 ADA_ZONE_FLAG_MAX_SEQ_SET = 0x0100,
200 ADA_ZONE_FLAG_SET_MASK = (ADA_ZONE_FLAG_OPT_SEQ_SET |
201 ADA_ZONE_FLAG_OPT_NONSEQ_SET |
202 ADA_ZONE_FLAG_MAX_SEQ_SET)
203 } ada_zone_flags;
204
205 static struct ada_zone_desc {
206 ada_zone_flags value;
207 const char *desc;
208 } ada_zone_desc_table[] = {
209 {ADA_ZONE_FLAG_RZ_SUP, "Report Zones" },
210 {ADA_ZONE_FLAG_OPEN_SUP, "Open" },
211 {ADA_ZONE_FLAG_CLOSE_SUP, "Close" },
212 {ADA_ZONE_FLAG_FINISH_SUP, "Finish" },
213 {ADA_ZONE_FLAG_RWP_SUP, "Reset Write Pointer" },
214 };
215
216 /* Offsets into our private area for storing information */
217 #define ccb_state ppriv_field0
218 #define ccb_bp ppriv_ptr1
219
220 typedef enum {
221 ADA_DELETE_NONE,
222 ADA_DELETE_DISABLE,
223 ADA_DELETE_CFA_ERASE,
224 ADA_DELETE_DSM_TRIM,
225 ADA_DELETE_NCQ_DSM_TRIM,
226 ADA_DELETE_MIN = ADA_DELETE_CFA_ERASE,
227 ADA_DELETE_MAX = ADA_DELETE_NCQ_DSM_TRIM,
228 } ada_delete_methods;
229
230 static const char *ada_delete_method_names[] =
231 { "NONE", "DISABLE", "CFA_ERASE", "DSM_TRIM", "NCQ_DSM_TRIM" };
232 #if 0
233 static const char *ada_delete_method_desc[] =
234 { "NONE", "DISABLED", "CFA Erase", "DSM Trim", "DSM Trim via NCQ" };
235 #endif
236
237 struct disk_params {
238 uint8_t heads;
239 uint8_t secs_per_track;
240 uint32_t cylinders;
241 uint32_t secsize; /* Number of bytes/logical sector */
242 uint64_t sectors; /* Total number sectors */
243 };
244
245 #define TRIM_MAX_BLOCKS 8
246 #define TRIM_MAX_RANGES (TRIM_MAX_BLOCKS * ATA_DSM_BLK_RANGES)
247 struct trim_request {
248 uint8_t data[TRIM_MAX_RANGES * ATA_DSM_RANGE_SIZE];
249 TAILQ_HEAD(, bio) bps;
250 };
251
252 struct ada_softc {
253 struct cam_iosched_softc *cam_iosched;
254 int outstanding_cmds; /* Number of active commands */
255 int refcount; /* Active xpt_action() calls */
256 ada_state state;
257 ada_flags flags;
258 ada_zone_mode zone_mode;
259 ada_zone_flags zone_flags;
260 struct ata_gp_log_dir ata_logdir;
261 int valid_logdir_len;
262 struct ata_identify_log_pages ata_iddir;
263 int valid_iddir_len;
264 uint64_t optimal_seq_zones;
265 uint64_t optimal_nonseq_zones;
266 uint64_t max_seq_zones;
267 ada_quirks quirks;
268 ada_delete_methods delete_method;
269 int trim_max_ranges;
270 int read_ahead;
271 int write_cache;
272 #ifdef CAM_TEST_FAILURE
273 int force_read_error;
274 int force_write_error;
275 int periodic_read_error;
276 int periodic_read_count;
277 #endif
278 struct ccb_pathinq cpi;
279 struct disk_params params;
280 struct disk *disk;
281 struct task sysctl_task;
282 struct sysctl_ctx_list sysctl_ctx;
283 struct sysctl_oid *sysctl_tree;
284 struct callout sendordered_c;
285 struct trim_request trim_req;
286 uint64_t trim_count;
287 uint64_t trim_ranges;
288 uint64_t trim_lbas;
289 #ifdef CAM_IO_STATS
290 struct sysctl_ctx_list sysctl_stats_ctx;
291 struct sysctl_oid *sysctl_stats_tree;
292 u_int timeouts;
293 u_int errors;
294 u_int invalidations;
295 #endif
296 #define ADA_ANNOUNCETMP_SZ 80
297 char announce_temp[ADA_ANNOUNCETMP_SZ];
298 #define ADA_ANNOUNCE_SZ 400
299 char announce_buffer[ADA_ANNOUNCE_SZ];
300 };
301
302 static uma_zone_t ada_ccb_zone;
303
304 struct ada_quirk_entry {
305 struct scsi_inquiry_pattern inq_pat;
306 ada_quirks quirks;
307 };
308
309 static struct ada_quirk_entry ada_quirk_table[] =
310 {
311 {
312 /* Sandisk X400 */
313 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SanDisk?SD8SB8U1T00*", "X4162000*" },
314 /*quirks*/ADA_Q_128KB
315 },
316 {
317 /* Hitachi Advanced Format (4k) drives */
318 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Hitachi H??????????E3*", "*" },
319 /*quirks*/ADA_Q_4K
320 },
321 {
322 /* Samsung Advanced Format (4k) drives */
323 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD155UI*", "*" },
324 /*quirks*/ADA_Q_4K
325 },
326 {
327 /* Samsung Advanced Format (4k) drives */
328 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD204UI*", "*" },
329 /*quirks*/ADA_Q_4K
330 },
331 {
332 /* Seagate Barracuda Green Advanced Format (4k) drives */
333 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DL*", "*" },
334 /*quirks*/ADA_Q_4K
335 },
336 {
337 /* Seagate Barracuda Advanced Format (4k) drives */
338 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???DM*", "*" },
339 /*quirks*/ADA_Q_4K
340 },
341 {
342 /* Seagate Barracuda Advanced Format (4k) drives */
343 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST????DM*", "*" },
344 /*quirks*/ADA_Q_4K
345 },
346 {
347 /* Seagate Momentus Advanced Format (4k) drives */
348 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500423AS*", "*" },
349 /*quirks*/ADA_Q_4K
350 },
351 {
352 /* Seagate Momentus Advanced Format (4k) drives */
353 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9500424AS*", "*" },
354 /*quirks*/ADA_Q_4K
355 },
356 {
357 /* Seagate Momentus Advanced Format (4k) drives */
358 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640423AS*", "*" },
359 /*quirks*/ADA_Q_4K
360 },
361 {
362 /* Seagate Momentus Advanced Format (4k) drives */
363 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9640424AS*", "*" },
364 /*quirks*/ADA_Q_4K
365 },
366 {
367 /* Seagate Momentus Advanced Format (4k) drives */
368 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750420AS*", "*" },
369 /*quirks*/ADA_Q_4K
370 },
371 {
372 /* Seagate Momentus Advanced Format (4k) drives */
373 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750422AS*", "*" },
374 /*quirks*/ADA_Q_4K
375 },
376 {
377 /* Seagate Momentus Advanced Format (4k) drives */
378 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST9750423AS*", "*" },
379 /*quirks*/ADA_Q_4K
380 },
381 {
382 /* Seagate Momentus Thin Advanced Format (4k) drives */
383 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST???LT*", "*" },
384 /*quirks*/ADA_Q_4K
385 },
386 {
387 /* WDC Caviar Red Advanced Format (4k) drives */
388 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????CX*", "*" },
389 /*quirks*/ADA_Q_4K
390 },
391 {
392 /* WDC Caviar Green Advanced Format (4k) drives */
393 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RS*", "*" },
394 /*quirks*/ADA_Q_4K
395 },
396 {
397 /* WDC Caviar Green/Red Advanced Format (4k) drives */
398 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????RX*", "*" },
399 /*quirks*/ADA_Q_4K
400 },
401 {
402 /* WDC Caviar Red Advanced Format (4k) drives */
403 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????CX*", "*" },
404 /*quirks*/ADA_Q_4K
405 },
406 {
407 /* WDC Caviar Black Advanced Format (4k) drives */
408 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????AZEX*", "*" },
409 /*quirks*/ADA_Q_4K
410 },
411 {
412 /* WDC Caviar Black Advanced Format (4k) drives */
413 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD????FZEX*", "*" },
414 /*quirks*/ADA_Q_4K
415 },
416 {
417 /* WDC Caviar Green Advanced Format (4k) drives */
418 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RS*", "*" },
419 /*quirks*/ADA_Q_4K
420 },
421 {
422 /* WDC Caviar Green Advanced Format (4k) drives */
423 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD??????RX*", "*" },
424 /*quirks*/ADA_Q_4K
425 },
426 {
427 /* WDC Scorpio Black Advanced Format (4k) drives */
428 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PKT*", "*" },
429 /*quirks*/ADA_Q_4K
430 },
431 {
432 /* WDC Scorpio Black Advanced Format (4k) drives */
433 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PKT*", "*" },
434 /*quirks*/ADA_Q_4K
435 },
436 {
437 /* WDC Scorpio Blue Advanced Format (4k) drives */
438 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD???PVT*", "*" },
439 /*quirks*/ADA_Q_4K
440 },
441 {
442 /* WDC Scorpio Blue Advanced Format (4k) drives */
443 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WD?????PVT*", "*" },
444 /*quirks*/ADA_Q_4K
445 },
446 /* SSDs */
447 {
448 /*
449 * Corsair Force 2 SSDs
450 * 4k optimised & trim only works in 4k requests + 4k aligned
451 */
452 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair CSSD-F*", "*" },
453 /*quirks*/ADA_Q_4K
454 },
455 {
456 /*
457 * Corsair Force 3 SSDs
458 * 4k optimised & trim only works in 4k requests + 4k aligned
459 */
460 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Force 3*", "*" },
461 /*quirks*/ADA_Q_4K
462 },
463 {
464 /*
465 * Corsair Neutron GTX SSDs
466 * 4k optimised & trim only works in 4k requests + 4k aligned
467 */
468 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Neutron GTX*", "*" },
469 /*quirks*/ADA_Q_4K
470 },
471 {
472 /*
473 * Corsair Force GT & GS SSDs
474 * 4k optimised & trim only works in 4k requests + 4k aligned
475 */
476 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Corsair Force G*", "*" },
477 /*quirks*/ADA_Q_4K
478 },
479 {
480 /*
481 * Crucial M4 SSDs
482 * 4k optimised & trim only works in 4k requests + 4k aligned
483 */
484 { T_DIRECT, SIP_MEDIA_FIXED, "*", "M4-CT???M4SSD2*", "*" },
485 /*quirks*/ADA_Q_4K
486 },
487 {
488 /*
489 * Crucial M500 SSDs MU07 firmware
490 * NCQ Trim works
491 */
492 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M500*", "MU07" },
493 /*quirks*/0
494 },
495 {
496 /*
497 * Crucial M500 SSDs all other firmware
498 * NCQ Trim doesn't work
499 */
500 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M500*", "*" },
501 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
502 },
503 {
504 /*
505 * Crucial M550 SSDs
506 * NCQ Trim doesn't work, but only on MU01 firmware
507 */
508 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*M550*", "MU01" },
509 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
510 },
511 {
512 /*
513 * Crucial MX100 SSDs
514 * NCQ Trim doesn't work, but only on MU01 firmware
515 */
516 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Crucial CT*MX100*", "MU01" },
517 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
518 },
519 {
520 /*
521 * Crucial RealSSD C300 SSDs
522 * 4k optimised
523 */
524 { T_DIRECT, SIP_MEDIA_FIXED, "*", "C300-CTFDDAC???MAG*",
525 "*" }, /*quirks*/ADA_Q_4K
526 },
527 {
528 /*
529 * FCCT M500 SSDs
530 * NCQ Trim doesn't work
531 */
532 { T_DIRECT, SIP_MEDIA_FIXED, "*", "FCCT*M500*", "*" },
533 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
534 },
535 {
536 /*
537 * Intel 320 Series SSDs
538 * 4k optimised & trim only works in 4k requests + 4k aligned
539 */
540 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSA2CW*", "*" },
541 /*quirks*/ADA_Q_4K
542 },
543 {
544 /*
545 * Intel 330 Series SSDs
546 * 4k optimised & trim only works in 4k requests + 4k aligned
547 */
548 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2CT*", "*" },
549 /*quirks*/ADA_Q_4K
550 },
551 {
552 /*
553 * Intel 510 Series SSDs
554 * 4k optimised & trim only works in 4k requests + 4k aligned
555 */
556 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2MH*", "*" },
557 /*quirks*/ADA_Q_4K
558 },
559 {
560 /*
561 * Intel 520 Series SSDs
562 * 4k optimised & trim only works in 4k requests + 4k aligned
563 */
564 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BW*", "*" },
565 /*quirks*/ADA_Q_4K
566 },
567 {
568 /*
569 * Intel S3610 Series SSDs
570 * 4k optimised & trim only works in 4k requests + 4k aligned
571 */
572 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSC2BX*", "*" },
573 /*quirks*/ADA_Q_4K
574 },
575 {
576 /*
577 * Intel X25-M Series SSDs
578 * 4k optimised & trim only works in 4k requests + 4k aligned
579 */
580 { T_DIRECT, SIP_MEDIA_FIXED, "*", "INTEL SSDSA2M*", "*" },
581 /*quirks*/ADA_Q_4K
582 },
583 {
584 /*
585 * KingDian S200 60GB P0921B
586 * Trimming crash the SSD
587 */
588 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KingDian S200 *", "*" },
589 /*quirks*/ADA_Q_NO_TRIM
590 },
591 {
592 /*
593 * Kingston E100 Series SSDs
594 * 4k optimised & trim only works in 4k requests + 4k aligned
595 */
596 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KINGSTON SE100S3*", "*" },
597 /*quirks*/ADA_Q_4K
598 },
599 {
600 /*
601 * Kingston HyperX 3k SSDs
602 * 4k optimised & trim only works in 4k requests + 4k aligned
603 */
604 { T_DIRECT, SIP_MEDIA_FIXED, "*", "KINGSTON SH103S3*", "*" },
605 /*quirks*/ADA_Q_4K
606 },
607 {
608 /*
609 * Marvell SSDs (entry taken from OpenSolaris)
610 * 4k optimised & trim only works in 4k requests + 4k aligned
611 */
612 { T_DIRECT, SIP_MEDIA_FIXED, "*", "MARVELL SD88SA02*", "*" },
613 /*quirks*/ADA_Q_4K
614 },
615 {
616 /*
617 * Micron M500 SSDs firmware MU07
618 * NCQ Trim works?
619 */
620 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M500*", "MU07" },
621 /*quirks*/0
622 },
623 {
624 /*
625 * Micron M500 SSDs all other firmware
626 * NCQ Trim doesn't work
627 */
628 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M500*", "*" },
629 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
630 },
631 {
632 /*
633 * Micron M5[15]0 SSDs
634 * NCQ Trim doesn't work, but only MU01 firmware
635 */
636 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron M5[15]0*", "MU01" },
637 /*quirks*/ADA_Q_NCQ_TRIM_BROKEN
638 },
639 {
640 /*
641 * Micron 5100 SSDs
642 * 4k optimised & trim only works in 4k requests + 4k aligned
643 */
644 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Micron 5100 MTFDDAK*", "*" },
645 /*quirks*/ADA_Q_4K
646 },
647 {
648 /*
649 * OCZ Agility 2 SSDs
650 * 4k optimised & trim only works in 4k requests + 4k aligned
651 */
652 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY2*", "*" },
653 /*quirks*/ADA_Q_4K
654 },
655 {
656 /*
657 * OCZ Agility 3 SSDs
658 * 4k optimised & trim only works in 4k requests + 4k aligned
659 */
660 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-AGILITY3*", "*" },
661 /*quirks*/ADA_Q_4K
662 },
663 {
664 /*
665 * OCZ Deneva R Series SSDs
666 * 4k optimised & trim only works in 4k requests + 4k aligned
667 */
668 { T_DIRECT, SIP_MEDIA_FIXED, "*", "DENRSTE251M45*", "*" },
669 /*quirks*/ADA_Q_4K
670 },
671 {
672 /*
673 * OCZ Vertex 2 SSDs (inc pro series)
674 * 4k optimised & trim only works in 4k requests + 4k aligned
675 */
676 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ?VERTEX2*", "*" },
677 /*quirks*/ADA_Q_4K
678 },
679 {
680 /*
681 * OCZ Vertex 3 SSDs
682 * 4k optimised & trim only works in 4k requests + 4k aligned
683 */
684 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX3*", "*" },
685 /*quirks*/ADA_Q_4K
686 },
687 {
688 /*
689 * OCZ Vertex 4 SSDs
690 * 4k optimised & trim only works in 4k requests + 4k aligned
691 */
692 { T_DIRECT, SIP_MEDIA_FIXED, "*", "OCZ-VERTEX4*", "*" },
693 /*quirks*/ADA_Q_4K
694 },
695 {
696 /*
697 * Samsung 750 SSDs
698 * 4k optimised, NCQ TRIM seems to work
699 */
700 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 750*", "*" },
701 /*quirks*/ADA_Q_4K
702 },
703 {
704 /*
705 * Samsung 830 Series SSDs
706 * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
707 */
708 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG SSD 830 Series*", "*" },
709 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
710 },
711 {
712 /*
713 * Samsung 840 SSDs
714 * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
715 */
716 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 840*", "*" },
717 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
718 },
719 {
720 /*
721 * Samsung 845 SSDs
722 * 4k optimised, NCQ TRIM Broken (normal TRIM is fine)
723 */
724 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 845*", "*" },
725 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
726 },
727 {
728 /*
729 * Samsung 850 SSDs
730 * 4k optimised, NCQ TRIM broken (normal TRIM fine)
731 */
732 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 850*", "*" },
733 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
734 },
735 {
736 /*
737 * Samsung 860 SSDs
738 * 4k optimised, NCQ TRIM broken (normal TRIM fine)
739 */
740 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 860*", "*" },
741 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
742 },
743 {
744 /*
745 * Samsung 870 SSDs
746 * 4k optimised, NCQ TRIM broken (normal TRIM fine)
747 */
748 { T_DIRECT, SIP_MEDIA_FIXED, "*", "Samsung SSD 870*", "*" },
749 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
750 },
751 {
752 /*
753 * Samsung SM863 Series SSDs (MZ7KM*)
754 * 4k optimised, NCQ believed to be working
755 */
756 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG MZ7KM*", "*" },
757 /*quirks*/ADA_Q_4K
758 },
759 {
760 /*
761 * Samsung 843T Series SSDs (MZ7WD*)
762 * Samsung PM851 Series SSDs (MZ7TE*)
763 * Samsung PM853T Series SSDs (MZ7GE*)
764 * 4k optimised, NCQ believed to be broken since these are
765 * appear to be built with the same controllers as the 840/850.
766 */
767 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG MZ7*", "*" },
768 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
769 },
770 {
771 /*
772 * Same as for SAMSUNG MZ7* but enable the quirks for SSD
773 * starting with MZ7* too
774 */
775 { T_DIRECT, SIP_MEDIA_FIXED, "*", "MZ7*", "*" },
776 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
777 },
778 {
779 /*
780 * Samsung PM851 Series SSDs Dell OEM
781 * device model "SAMSUNG SSD PM851 mSATA 256GB"
782 * 4k optimised, NCQ broken
783 */
784 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG SSD PM851*", "*" },
785 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
786 },
787 {
788 /*
789 * SuperTalent TeraDrive CT SSDs
790 * 4k optimised & trim only works in 4k requests + 4k aligned
791 */
792 { T_DIRECT, SIP_MEDIA_FIXED, "*", "FTM??CT25H*", "*" },
793 /*quirks*/ADA_Q_4K
794 },
795 {
796 /*
797 * XceedIOPS SATA SSDs
798 * 4k optimised
799 */
800 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SG9XCS2D*", "*" },
801 /*quirks*/ADA_Q_4K
802 },
803 {
804 /*
805 * Samsung drive that doesn't support READ LOG EXT or
806 * READ LOG DMA EXT, despite reporting that it does in
807 * ATA identify data:
808 * SAMSUNG HD200HJ KF100-06
809 */
810 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD200*", "*" },
811 /*quirks*/ADA_Q_LOG_BROKEN
812 },
813 {
814 /*
815 * Samsung drive that doesn't support READ LOG EXT or
816 * READ LOG DMA EXT, despite reporting that it does in
817 * ATA identify data:
818 * SAMSUNG HD501LJ CR100-10
819 */
820 { T_DIRECT, SIP_MEDIA_FIXED, "*", "SAMSUNG HD501*", "*" },
821 /*quirks*/ADA_Q_LOG_BROKEN
822 },
823 {
824 /*
825 * Seagate Lamarr 8TB Shingled Magnetic Recording (SMR)
826 * Drive Managed SATA hard drive. This drive doesn't report
827 * in firmware that it is a drive managed SMR drive.
828 */
829 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ST8000AS000[23]*", "*" },
830 /*quirks*/ADA_Q_SMR_DM
831 },
832 {
833 /* WD Green SSD */
834 { T_DIRECT, SIP_MEDIA_FIXED, "*", "WDC WDS?????G0*", "*" },
835 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
836 },
837 {
838 /* Seagate IronWolf 110 SATA SSD NCQ Trim is unstable */
839 { T_DIRECT, SIP_MEDIA_FIXED, "*", "ZA*NM*", "*" },
840 /*quirks*/ADA_Q_4K | ADA_Q_NCQ_TRIM_BROKEN
841 },
842 {
843 /* Default */
844 {
845 T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
846 /*vendor*/"*", /*product*/"*", /*revision*/"*"
847 },
848 /*quirks*/0
849 },
850 };
851
852 static disk_strategy_t adastrategy;
853 static dumper_t adadump;
854 static periph_init_t adainit;
855 static void adadiskgonecb(struct disk *dp);
856 static periph_oninv_t adaoninvalidate;
857 static periph_dtor_t adacleanup;
858 static void adaasync(void *callback_arg, uint32_t code,
859 struct cam_path *path, void *arg);
860 static int adabitsysctl(SYSCTL_HANDLER_ARGS);
861 static int adaflagssysctl(SYSCTL_HANDLER_ARGS);
862 static int adazonesupsysctl(SYSCTL_HANDLER_ARGS);
863 static void adasysctlinit(void *context, int pending);
864 static int adagetattr(struct bio *bp);
865 static void adasetflags(struct ada_softc *softc,
866 struct ccb_getdev *cgd);
867 static void adasetgeom(struct ada_softc *softc,
868 struct ccb_getdev *cgd);
869 static periph_ctor_t adaregister;
870 static void ada_dsmtrim(struct ada_softc *softc, struct bio *bp,
871 struct ccb_ataio *ataio);
872 static void ada_cfaerase(struct ada_softc *softc, struct bio *bp,
873 struct ccb_ataio *ataio);
874 static int ada_zone_bio_to_ata(int disk_zone_cmd);
875 static int ada_zone_cmd(struct cam_periph *periph, union ccb *ccb,
876 struct bio *bp, int *queue_ccb);
877 static periph_start_t adastart;
878 static void adaprobedone(struct cam_periph *periph, union ccb *ccb);
879 static void adazonedone(struct cam_periph *periph, union ccb *ccb);
880 static void adadone(struct cam_periph *periph,
881 union ccb *done_ccb);
882 static int adaerror(union ccb *ccb, uint32_t cam_flags,
883 uint32_t sense_flags);
884 static callout_func_t adasendorderedtag;
885 static void adashutdown(void *arg, int howto);
886 static void adasuspend(void *arg, enum power_stype stype);
887 static void adaresume(void *arg, enum power_stype stype);
888
889 #ifndef ADA_DEFAULT_TIMEOUT
890 #define ADA_DEFAULT_TIMEOUT 30 /* Timeout in seconds */
891 #endif
892
893 #ifndef ADA_DEFAULT_RETRY
894 #define ADA_DEFAULT_RETRY 4
895 #endif
896
897 #ifndef ADA_DEFAULT_SEND_ORDERED
898 #define ADA_DEFAULT_SEND_ORDERED 1
899 #endif
900
901 #ifndef ADA_DEFAULT_SPINDOWN_SHUTDOWN
902 #define ADA_DEFAULT_SPINDOWN_SHUTDOWN 1
903 #endif
904
905 #ifndef ADA_DEFAULT_SPINDOWN_SUSPEND
906 #define ADA_DEFAULT_SPINDOWN_SUSPEND 1
907 #endif
908
909 #ifndef ADA_DEFAULT_READ_AHEAD
910 #define ADA_DEFAULT_READ_AHEAD 1
911 #endif
912
913 #ifndef ADA_DEFAULT_WRITE_CACHE
914 #define ADA_DEFAULT_WRITE_CACHE 1
915 #endif
916
917 #define ADA_RA (softc->read_ahead >= 0 ? \
918 softc->read_ahead : ada_read_ahead)
919 #define ADA_WC (softc->write_cache >= 0 ? \
920 softc->write_cache : ada_write_cache)
921
922 static int ada_retry_count = ADA_DEFAULT_RETRY;
923 static int ada_default_timeout = ADA_DEFAULT_TIMEOUT;
924 static int ada_send_ordered = ADA_DEFAULT_SEND_ORDERED;
925 static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOWN_SHUTDOWN;
926 static int ada_spindown_suspend = ADA_DEFAULT_SPINDOWN_SUSPEND;
927 static int ada_read_ahead = ADA_DEFAULT_READ_AHEAD;
928 static int ada_write_cache = ADA_DEFAULT_WRITE_CACHE;
929 static int ada_enable_biospeedup = 1;
930 static int ada_enable_uma_ccbs = 1;
931
932 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
933 "CAM Direct Access Disk driver");
934 SYSCTL_INT(_kern_cam_ada, OID_AUTO, retry_count, CTLFLAG_RWTUN,
935 &ada_retry_count, 0, "Normal I/O retry count");
936 SYSCTL_INT(_kern_cam_ada, OID_AUTO, default_timeout, CTLFLAG_RWTUN,
937 &ada_default_timeout, 0, "Normal I/O timeout (in seconds)");
938 SYSCTL_INT(_kern_cam_ada, OID_AUTO, send_ordered, CTLFLAG_RWTUN,
939 &ada_send_ordered, 0, "Send Ordered Tags");
940 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_shutdown, CTLFLAG_RWTUN,
941 &ada_spindown_shutdown, 0, "Spin down upon shutdown");
942 SYSCTL_INT(_kern_cam_ada, OID_AUTO, spindown_suspend, CTLFLAG_RWTUN,
943 &ada_spindown_suspend, 0, "Spin down upon suspend");
944 SYSCTL_INT(_kern_cam_ada, OID_AUTO, read_ahead, CTLFLAG_RWTUN,
945 &ada_read_ahead, 0, "Enable disk read-ahead");
946 SYSCTL_INT(_kern_cam_ada, OID_AUTO, write_cache, CTLFLAG_RWTUN,
947 &ada_write_cache, 0, "Enable disk write cache");
948 SYSCTL_INT(_kern_cam_ada, OID_AUTO, enable_biospeedup, CTLFLAG_RDTUN,
949 &ada_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
950 SYSCTL_INT(_kern_cam_ada, OID_AUTO, enable_uma_ccbs, CTLFLAG_RWTUN,
951 &ada_enable_uma_ccbs, 0, "Use UMA for CCBs");
952
953 /*
954 * ADA_ORDEREDTAG_INTERVAL determines how often, relative
955 * to the default timeout, we check to see whether an ordered
956 * tagged transaction is appropriate to prevent simple tag
957 * starvation. Since we'd like to ensure that there is at least
958 * 1/2 of the timeout length left for a starved transaction to
959 * complete after we've sent an ordered tag, we must poll at least
960 * four times in every timeout period. This takes care of the worst
961 * case where a starved transaction starts during an interval that
962 * meets the requirement "don't send an ordered tag" test so it takes
963 * us two intervals to determine that a tag must be sent.
964 */
965 #ifndef ADA_ORDEREDTAG_INTERVAL
966 #define ADA_ORDEREDTAG_INTERVAL 4
967 #endif
968
969 static struct periph_driver adadriver =
970 {
971 adainit, "ada",
972 TAILQ_HEAD_INITIALIZER(adadriver.units), /* generation */ 0
973 };
974
975 static int adadeletemethodsysctl(SYSCTL_HANDLER_ARGS);
976
977 PERIPHDRIVER_DECLARE(ada, adadriver);
978
979 static MALLOC_DEFINE(M_ATADA, "ata_da", "ata_da buffers");
980
981 static int
adaopen(struct disk * dp)982 adaopen(struct disk *dp)
983 {
984 struct cam_periph *periph;
985 struct ada_softc *softc;
986 int error;
987
988 periph = (struct cam_periph *)dp->d_drv1;
989 if (cam_periph_acquire(periph) != 0) {
990 return(ENXIO);
991 }
992
993 cam_periph_lock(periph);
994 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) {
995 cam_periph_unlock(periph);
996 cam_periph_release(periph);
997 return (error);
998 }
999
1000 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1001 ("adaopen\n"));
1002
1003 softc = (struct ada_softc *)periph->softc;
1004 softc->flags |= ADA_FLAG_OPEN;
1005
1006 cam_periph_unhold(periph);
1007 cam_periph_unlock(periph);
1008 return (0);
1009 }
1010
1011 static int
adaclose(struct disk * dp)1012 adaclose(struct disk *dp)
1013 {
1014 struct cam_periph *periph;
1015 struct ada_softc *softc;
1016 union ccb *ccb;
1017 int error;
1018
1019 periph = (struct cam_periph *)dp->d_drv1;
1020 softc = (struct ada_softc *)periph->softc;
1021 cam_periph_lock(periph);
1022
1023 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
1024 ("adaclose\n"));
1025
1026 /* We only sync the cache if the drive is capable of it. */
1027 if ((softc->flags & ADA_FLAG_DIRTY) != 0 &&
1028 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
1029 (periph->flags & CAM_PERIPH_INVALID) == 0 &&
1030 cam_periph_hold(periph, PRIBIO) == 0) {
1031 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
1032 cam_fill_ataio(&ccb->ataio,
1033 1,
1034 NULL,
1035 CAM_DIR_NONE,
1036 0,
1037 NULL,
1038 0,
1039 ada_default_timeout*1000);
1040
1041 if (softc->flags & ADA_FLAG_CAN_48BIT)
1042 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1043 else
1044 ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
1045 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
1046 /*sense_flags*/0, softc->disk->d_devstat);
1047
1048 if (error != 0)
1049 xpt_print(periph->path, "Synchronize cache failed\n");
1050 softc->flags &= ~ADA_FLAG_DIRTY;
1051 xpt_release_ccb(ccb);
1052 cam_periph_unhold(periph);
1053 }
1054
1055 softc->flags &= ~ADA_FLAG_OPEN;
1056
1057 while (softc->refcount != 0)
1058 cam_periph_sleep(periph, &softc->refcount, PRIBIO, "adaclose", 1);
1059 cam_periph_unlock(periph);
1060 cam_periph_release(periph);
1061 return (0);
1062 }
1063
1064 static void
adaschedule(struct cam_periph * periph)1065 adaschedule(struct cam_periph *periph)
1066 {
1067 struct ada_softc *softc = (struct ada_softc *)periph->softc;
1068
1069 if (softc->state != ADA_STATE_NORMAL)
1070 return;
1071
1072 cam_iosched_schedule(softc->cam_iosched, periph);
1073 }
1074
1075 /*
1076 * Actually translate the requested transfer into one the physical driver
1077 * can understand. The transfer is described by a buf and will include
1078 * only one physical transfer.
1079 */
1080 static void
adastrategy(struct bio * bp)1081 adastrategy(struct bio *bp)
1082 {
1083 struct cam_periph *periph;
1084 struct ada_softc *softc;
1085
1086 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1087 softc = (struct ada_softc *)periph->softc;
1088
1089 cam_periph_lock(periph);
1090
1091 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastrategy(%p)\n", bp));
1092
1093 /*
1094 * If the device has been made invalid, error out
1095 */
1096 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
1097 cam_periph_unlock(periph);
1098 biofinish(bp, NULL, ENXIO);
1099 return;
1100 }
1101
1102 /*
1103 * Zone commands must be ordered, because they can depend on the
1104 * effects of previously issued commands, and they may affect
1105 * commands after them.
1106 */
1107 if (bp->bio_cmd == BIO_ZONE)
1108 bp->bio_flags |= BIO_ORDERED;
1109
1110 /*
1111 * Place it in the queue of disk activities for this disk
1112 */
1113 cam_iosched_queue_work(softc->cam_iosched, bp);
1114
1115 /*
1116 * Schedule ourselves for performing the work.
1117 */
1118 adaschedule(periph);
1119 cam_periph_unlock(periph);
1120
1121 return;
1122 }
1123
1124 static int
adadump(void * arg,void * virtual,off_t offset,size_t length)1125 adadump(void *arg, void *virtual, off_t offset, size_t length)
1126 {
1127 struct cam_periph *periph;
1128 struct ada_softc *softc;
1129 u_int secsize;
1130 struct ccb_ataio ataio;
1131 struct disk *dp;
1132 uint64_t lba;
1133 uint16_t count;
1134 int error = 0;
1135
1136 dp = arg;
1137 periph = dp->d_drv1;
1138 softc = (struct ada_softc *)periph->softc;
1139 secsize = softc->params.secsize;
1140 lba = offset / secsize;
1141 count = length / secsize;
1142 if ((periph->flags & CAM_PERIPH_INVALID) != 0)
1143 return (ENXIO);
1144
1145 memset(&ataio, 0, sizeof(ataio));
1146 if (length > 0) {
1147 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1148 ataio.ccb_h.ccb_state = ADA_CCB_DUMP;
1149 cam_fill_ataio(&ataio,
1150 0,
1151 NULL,
1152 CAM_DIR_OUT,
1153 0,
1154 (uint8_t *) virtual,
1155 length,
1156 ada_default_timeout*1000);
1157 if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
1158 (lba + count >= ATA_MAX_28BIT_LBA ||
1159 count >= 256)) {
1160 ata_48bit_cmd(&ataio, ATA_WRITE_DMA48,
1161 0, lba, count);
1162 } else {
1163 ata_28bit_cmd(&ataio, ATA_WRITE_DMA,
1164 0, lba, count);
1165 }
1166 error = cam_periph_runccb((union ccb *)&ataio, adaerror,
1167 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1168 if (error != 0)
1169 printf("Aborting dump due to I/O error.\n");
1170
1171 return (error);
1172 }
1173
1174 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
1175 xpt_setup_ccb(&ataio.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
1176
1177 /*
1178 * Tell the drive to flush its internal cache. if we
1179 * can't flush in 5s we have big problems. No need to
1180 * wait the default 60s to detect problems.
1181 */
1182 ataio.ccb_h.ccb_state = ADA_CCB_DUMP;
1183 cam_fill_ataio(&ataio,
1184 0,
1185 NULL,
1186 CAM_DIR_NONE,
1187 0,
1188 NULL,
1189 0,
1190 5*1000);
1191
1192 if (softc->flags & ADA_FLAG_CAN_48BIT)
1193 ata_48bit_cmd(&ataio, ATA_FLUSHCACHE48, 0, 0, 0);
1194 else
1195 ata_28bit_cmd(&ataio, ATA_FLUSHCACHE, 0, 0, 0);
1196 error = cam_periph_runccb((union ccb *)&ataio, adaerror,
1197 0, SF_NO_RECOVERY | SF_NO_RETRY, NULL);
1198 if (error != 0)
1199 xpt_print(periph->path, "Synchronize cache failed\n");
1200 }
1201 return (error);
1202 }
1203
1204 static void
adainit(void)1205 adainit(void)
1206 {
1207 cam_status status;
1208
1209 ada_ccb_zone = uma_zcreate("ada_ccb",
1210 sizeof(struct ccb_ataio), NULL, NULL, NULL, NULL,
1211 UMA_ALIGN_PTR, 0);
1212
1213 /*
1214 * Install a global async callback. This callback will
1215 * receive async callbacks like "new device found".
1216 */
1217 status = xpt_register_async(AC_FOUND_DEVICE, adaasync, NULL, NULL);
1218
1219 if (status != CAM_REQ_CMP) {
1220 printf("ada: Failed to attach master async callback "
1221 "due to status 0x%x!\n", status);
1222 } else if (ada_send_ordered) {
1223 /* Register our event handlers */
1224 if ((EVENTHANDLER_REGISTER(power_suspend, adasuspend,
1225 NULL, EVENTHANDLER_PRI_LAST)) == NULL)
1226 printf("adainit: power event registration failed!\n");
1227 if ((EVENTHANDLER_REGISTER(power_resume, adaresume,
1228 NULL, EVENTHANDLER_PRI_LAST)) == NULL)
1229 printf("adainit: power event registration failed!\n");
1230 if ((EVENTHANDLER_REGISTER(shutdown_post_sync, adashutdown,
1231 NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
1232 printf("adainit: shutdown event registration failed!\n");
1233 }
1234 }
1235
1236 /*
1237 * Callback from GEOM, called when it has finished cleaning up its
1238 * resources.
1239 */
1240 static void
adadiskgonecb(struct disk * dp)1241 adadiskgonecb(struct disk *dp)
1242 {
1243 struct cam_periph *periph;
1244
1245 periph = (struct cam_periph *)dp->d_drv1;
1246
1247 cam_periph_release(periph);
1248 }
1249
1250 static void
adaoninvalidate(struct cam_periph * periph)1251 adaoninvalidate(struct cam_periph *periph)
1252 {
1253 struct ada_softc *softc;
1254
1255 softc = (struct ada_softc *)periph->softc;
1256
1257 /*
1258 * De-register any async callbacks.
1259 */
1260 xpt_register_async(0, adaasync, periph, periph->path);
1261 #ifdef CAM_IO_STATS
1262 softc->invalidations++;
1263 #endif
1264
1265 /*
1266 * Return all queued I/O with ENXIO. Transactions may be queued up here
1267 * for retry (since we are called while there's other transactions
1268 * pending). Any requests in the hardware will drain before ndacleanup
1269 * is called.
1270 */
1271 cam_iosched_flush(softc->cam_iosched, NULL, ENXIO);
1272
1273 /*
1274 * Tell GEOM that we've gone away, we'll get a callback when it is
1275 * done cleaning up its resources.
1276 */
1277 disk_gone(softc->disk);
1278 }
1279
1280 static void
adacleanup(struct cam_periph * periph)1281 adacleanup(struct cam_periph *periph)
1282 {
1283 struct ada_softc *softc;
1284
1285 softc = (struct ada_softc *)periph->softc;
1286
1287 cam_periph_unlock(periph);
1288
1289 cam_iosched_fini(softc->cam_iosched);
1290
1291 /*
1292 * If we can't free the sysctl tree, oh well...
1293 */
1294 if ((softc->flags & ADA_FLAG_SCTX_INIT) != 0) {
1295 #ifdef CAM_IO_STATS
1296 if (sysctl_ctx_free(&softc->sysctl_stats_ctx) != 0)
1297 xpt_print(periph->path,
1298 "can't remove sysctl stats context\n");
1299 #endif
1300 if (sysctl_ctx_free(&softc->sysctl_ctx) != 0)
1301 xpt_print(periph->path,
1302 "can't remove sysctl context\n");
1303 }
1304
1305 disk_destroy(softc->disk);
1306 callout_drain(&softc->sendordered_c);
1307 free(softc, M_DEVBUF);
1308 cam_periph_lock(periph);
1309 }
1310
1311 static void
adasetdeletemethod(struct ada_softc * softc)1312 adasetdeletemethod(struct ada_softc *softc)
1313 {
1314
1315 if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
1316 softc->delete_method = ADA_DELETE_NCQ_DSM_TRIM;
1317 else if (softc->flags & ADA_FLAG_CAN_TRIM)
1318 softc->delete_method = ADA_DELETE_DSM_TRIM;
1319 else if ((softc->flags & ADA_FLAG_CAN_CFA) && !(softc->flags & ADA_FLAG_CAN_48BIT))
1320 softc->delete_method = ADA_DELETE_CFA_ERASE;
1321 else
1322 softc->delete_method = ADA_DELETE_NONE;
1323 }
1324
1325 static void
adaasync(void * callback_arg,uint32_t code,struct cam_path * path,void * arg)1326 adaasync(void *callback_arg, uint32_t code,
1327 struct cam_path *path, void *arg)
1328 {
1329 struct ccb_getdev cgd;
1330 struct cam_periph *periph;
1331 struct ada_softc *softc;
1332
1333 periph = (struct cam_periph *)callback_arg;
1334 switch (code) {
1335 case AC_FOUND_DEVICE:
1336 {
1337 struct ccb_getdev *cgd;
1338 cam_status status;
1339
1340 cgd = (struct ccb_getdev *)arg;
1341 if (cgd == NULL)
1342 break;
1343
1344 if (cgd->protocol != PROTO_ATA)
1345 break;
1346
1347 /*
1348 * Allocate a peripheral instance for
1349 * this device and start the probe
1350 * process.
1351 */
1352 status = cam_periph_alloc(adaregister, adaoninvalidate,
1353 adacleanup, adastart,
1354 "ada", CAM_PERIPH_BIO,
1355 path, adaasync,
1356 AC_FOUND_DEVICE, cgd);
1357
1358 if (status != CAM_REQ_CMP
1359 && status != CAM_REQ_INPROG)
1360 printf("adaasync: Unable to attach to new device "
1361 "due to status 0x%x\n", status);
1362 break;
1363 }
1364 case AC_GETDEV_CHANGED:
1365 {
1366 softc = (struct ada_softc *)periph->softc;
1367 xpt_gdev_type(&cgd, periph->path);
1368
1369 /*
1370 * Update our information based on the new Identify data.
1371 */
1372 adasetflags(softc, &cgd);
1373 adasetgeom(softc, &cgd);
1374 disk_resize(softc->disk, M_NOWAIT);
1375 break;
1376 }
1377 case AC_ADVINFO_CHANGED:
1378 {
1379 uintptr_t buftype;
1380
1381 buftype = (uintptr_t)arg;
1382 if (buftype == CDAI_TYPE_PHYS_PATH) {
1383 struct ada_softc *softc;
1384
1385 softc = periph->softc;
1386 disk_attr_changed(softc->disk, "GEOM::physpath",
1387 M_NOWAIT);
1388 }
1389 break;
1390 }
1391 case AC_SENT_BDR:
1392 case AC_BUS_RESET:
1393 {
1394 softc = (struct ada_softc *)periph->softc;
1395 if (softc->state != ADA_STATE_NORMAL)
1396 break;
1397 if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD)
1398 softc->state = ADA_STATE_RAHEAD;
1399 else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE)
1400 softc->state = ADA_STATE_WCACHE;
1401 else if ((softc->flags & ADA_FLAG_CAN_LOG)
1402 && (softc->zone_mode != ADA_ZONE_NONE))
1403 softc->state = ADA_STATE_LOGDIR;
1404 else
1405 break;
1406 if (cam_periph_acquire(periph) != 0)
1407 softc->state = ADA_STATE_NORMAL;
1408 else
1409 xpt_schedule(periph, CAM_PRIORITY_DEV);
1410 break;
1411 }
1412 default:
1413 break;
1414 }
1415 cam_periph_async(periph, code, path, arg);
1416 }
1417
1418 static int
adazonemodesysctl(SYSCTL_HANDLER_ARGS)1419 adazonemodesysctl(SYSCTL_HANDLER_ARGS)
1420 {
1421 char tmpbuf[40];
1422 struct ada_softc *softc;
1423 int error;
1424
1425 softc = (struct ada_softc *)arg1;
1426
1427 switch (softc->zone_mode) {
1428 case ADA_ZONE_DRIVE_MANAGED:
1429 snprintf(tmpbuf, sizeof(tmpbuf), "Drive Managed");
1430 break;
1431 case ADA_ZONE_HOST_AWARE:
1432 snprintf(tmpbuf, sizeof(tmpbuf), "Host Aware");
1433 break;
1434 case ADA_ZONE_HOST_MANAGED:
1435 snprintf(tmpbuf, sizeof(tmpbuf), "Host Managed");
1436 break;
1437 case ADA_ZONE_NONE:
1438 default:
1439 snprintf(tmpbuf, sizeof(tmpbuf), "Not Zoned");
1440 break;
1441 }
1442
1443 error = sysctl_handle_string(oidp, tmpbuf, sizeof(tmpbuf), req);
1444
1445 return (error);
1446 }
1447
1448 static int
adazonesupsysctl(SYSCTL_HANDLER_ARGS)1449 adazonesupsysctl(SYSCTL_HANDLER_ARGS)
1450 {
1451 struct ada_softc *softc;
1452 struct sbuf sb;
1453 int error, first;
1454 unsigned int i;
1455
1456 softc = (struct ada_softc *)arg1;
1457
1458 first = 1;
1459 sbuf_new_for_sysctl(&sb, NULL, 0, req);
1460
1461 for (i = 0; i < sizeof(ada_zone_desc_table) /
1462 sizeof(ada_zone_desc_table[0]); i++) {
1463 if (softc->zone_flags & ada_zone_desc_table[i].value) {
1464 if (first == 0)
1465 sbuf_cat(&sb, ", ");
1466 else
1467 first = 0;
1468 sbuf_cat(&sb, ada_zone_desc_table[i].desc);
1469 }
1470 }
1471
1472 if (first == 1)
1473 sbuf_cat(&sb, "None");
1474
1475 error = sbuf_finish(&sb);
1476 sbuf_delete(&sb);
1477 return (error);
1478 }
1479
1480 static void
adasysctlinit(void * context,int pending)1481 adasysctlinit(void *context, int pending)
1482 {
1483 struct cam_periph *periph;
1484 struct ada_softc *softc;
1485 char tmpstr[32], tmpstr2[16];
1486
1487 periph = (struct cam_periph *)context;
1488
1489 /* periph was held for us when this task was enqueued */
1490 if ((periph->flags & CAM_PERIPH_INVALID) != 0) {
1491 cam_periph_release(periph);
1492 return;
1493 }
1494
1495 softc = (struct ada_softc *)periph->softc;
1496 snprintf(tmpstr, sizeof(tmpstr), "CAM ADA unit %d",periph->unit_number);
1497 snprintf(tmpstr2, sizeof(tmpstr2), "%d", periph->unit_number);
1498
1499 sysctl_ctx_init(&softc->sysctl_ctx);
1500 softc->flags |= ADA_FLAG_SCTX_INIT;
1501 softc->sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(&softc->sysctl_ctx,
1502 SYSCTL_STATIC_CHILDREN(_kern_cam_ada), OID_AUTO, tmpstr2,
1503 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, tmpstr, "device_index");
1504 if (softc->sysctl_tree == NULL) {
1505 printf("adasysctlinit: unable to allocate sysctl tree\n");
1506 cam_periph_release(periph);
1507 return;
1508 }
1509
1510 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1511 OID_AUTO, "delete_method",
1512 CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_MPSAFE,
1513 softc, 0, adadeletemethodsysctl, "A",
1514 "BIO_DELETE execution method");
1515 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1516 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1517 "trim_count", CTLFLAG_RD, &softc->trim_count,
1518 "Total number of dsm commands sent");
1519 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1520 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1521 "trim_ranges", CTLFLAG_RD, &softc->trim_ranges,
1522 "Total number of ranges in dsm commands");
1523 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1524 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1525 "trim_lbas", CTLFLAG_RD, &softc->trim_lbas,
1526 "Total lbas in the dsm commands sent");
1527 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1528 OID_AUTO, "read_ahead", CTLFLAG_RW | CTLFLAG_MPSAFE,
1529 &softc->read_ahead, 0, "Enable disk read ahead.");
1530 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1531 OID_AUTO, "write_cache", CTLFLAG_RW | CTLFLAG_MPSAFE,
1532 &softc->write_cache, 0, "Enable disk write cache.");
1533 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1534 OID_AUTO, "zone_mode",
1535 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1536 softc, 0, adazonemodesysctl, "A",
1537 "Zone Mode");
1538 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1539 OID_AUTO, "zone_support",
1540 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1541 softc, 0, adazonesupsysctl, "A",
1542 "Zone Support");
1543 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1544 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1545 "optimal_seq_zones", CTLFLAG_RD, &softc->optimal_seq_zones,
1546 "Optimal Number of Open Sequential Write Preferred Zones");
1547 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1548 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1549 "optimal_nonseq_zones", CTLFLAG_RD,
1550 &softc->optimal_nonseq_zones,
1551 "Optimal Number of Non-Sequentially Written Sequential Write "
1552 "Preferred Zones");
1553 SYSCTL_ADD_UQUAD(&softc->sysctl_ctx,
1554 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO,
1555 "max_seq_zones", CTLFLAG_RD, &softc->max_seq_zones,
1556 "Maximum Number of Open Sequential Write Required Zones");
1557 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1558 OID_AUTO, "flags", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
1559 softc, 0, adaflagssysctl, "A",
1560 "Flags for drive");
1561 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1562 OID_AUTO, "unmapped_io", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
1563 &softc->flags, (u_int)ADA_FLAG_UNMAPPEDIO, adabitsysctl, "I",
1564 "Use unmapped I/O. This sysctl is *DEPRECATED*, gone in FreeBSD 16");
1565 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1566 OID_AUTO, "rotating", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE,
1567 &softc->flags, (u_int)ADA_FLAG_ROTATING, adabitsysctl, "I",
1568 "Rotating media. This sysctl is *DEPRECATED*, gone in FreeBSD 16");
1569
1570 #ifdef CAM_TEST_FAILURE
1571 /*
1572 * Add a 'door bell' sysctl which allows one to set it from userland
1573 * and cause something bad to happen. For the moment, we only allow
1574 * whacking the next read or write.
1575 */
1576 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1577 OID_AUTO, "force_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1578 &softc->force_read_error, 0,
1579 "Force a read error for the next N reads.");
1580 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1581 OID_AUTO, "force_write_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1582 &softc->force_write_error, 0,
1583 "Force a write error for the next N writes.");
1584 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1585 OID_AUTO, "periodic_read_error", CTLFLAG_RW | CTLFLAG_MPSAFE,
1586 &softc->periodic_read_error, 0,
1587 "Force a read error every N reads (don't set too low).");
1588 SYSCTL_ADD_PROC(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree),
1589 OID_AUTO, "invalidate", CTLTYPE_U64 | CTLFLAG_RW | CTLFLAG_MPSAFE,
1590 periph, 0, cam_periph_invalidate_sysctl, "I",
1591 "Write 1 to invalidate the drive immediately");
1592 #endif
1593
1594 #ifdef CAM_IO_STATS
1595 softc->sysctl_stats_tree = SYSCTL_ADD_NODE(&softc->sysctl_stats_ctx,
1596 SYSCTL_CHILDREN(softc->sysctl_tree), OID_AUTO, "stats",
1597 CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "Statistics");
1598 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1599 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1600 OID_AUTO, "timeouts", CTLFLAG_RD | CTLFLAG_MPSAFE,
1601 &softc->timeouts, 0,
1602 "Device timeouts reported by the SIM");
1603 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1604 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1605 OID_AUTO, "errors", CTLFLAG_RD | CTLFLAG_MPSAFE,
1606 &softc->errors, 0,
1607 "Transport errors reported by the SIM.");
1608 SYSCTL_ADD_INT(&softc->sysctl_stats_ctx,
1609 SYSCTL_CHILDREN(softc->sysctl_stats_tree),
1610 OID_AUTO, "pack_invalidations", CTLFLAG_RD | CTLFLAG_MPSAFE,
1611 &softc->invalidations, 0,
1612 "Device pack invalidations.");
1613 #endif
1614
1615 cam_iosched_sysctl_init(softc->cam_iosched, &softc->sysctl_ctx,
1616 softc->sysctl_tree);
1617
1618 cam_periph_release(periph);
1619 }
1620
1621 static int
adagetattr(struct bio * bp)1622 adagetattr(struct bio *bp)
1623 {
1624 int ret;
1625 struct cam_periph *periph;
1626
1627 if (g_handleattr_int(bp, "GEOM::canspeedup", ada_enable_biospeedup))
1628 return (EJUSTRETURN);
1629
1630 periph = (struct cam_periph *)bp->bio_disk->d_drv1;
1631 cam_periph_lock(periph);
1632 ret = xpt_getattr(bp->bio_data, bp->bio_length, bp->bio_attribute,
1633 periph->path);
1634 cam_periph_unlock(periph);
1635 if (ret == 0)
1636 bp->bio_completed = bp->bio_length;
1637 return ret;
1638 }
1639
1640 static int
adadeletemethodsysctl(SYSCTL_HANDLER_ARGS)1641 adadeletemethodsysctl(SYSCTL_HANDLER_ARGS)
1642 {
1643 char buf[16];
1644 const char *p;
1645 struct ada_softc *softc;
1646 int i, error, value, methods;
1647
1648 softc = (struct ada_softc *)arg1;
1649
1650 value = softc->delete_method;
1651 if (value < 0 || value > ADA_DELETE_MAX)
1652 p = "UNKNOWN";
1653 else
1654 p = ada_delete_method_names[value];
1655 strncpy(buf, p, sizeof(buf));
1656 error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
1657 if (error != 0 || req->newptr == NULL)
1658 return (error);
1659 methods = 1 << ADA_DELETE_DISABLE;
1660 if ((softc->flags & ADA_FLAG_CAN_CFA) &&
1661 !(softc->flags & ADA_FLAG_CAN_48BIT))
1662 methods |= 1 << ADA_DELETE_CFA_ERASE;
1663 if (softc->flags & ADA_FLAG_CAN_TRIM)
1664 methods |= 1 << ADA_DELETE_DSM_TRIM;
1665 if (softc->flags & ADA_FLAG_CAN_NCQ_TRIM)
1666 methods |= 1 << ADA_DELETE_NCQ_DSM_TRIM;
1667 for (i = 0; i <= ADA_DELETE_MAX; i++) {
1668 if (!(methods & (1 << i)) ||
1669 strcmp(buf, ada_delete_method_names[i]) != 0)
1670 continue;
1671 softc->delete_method = i;
1672 return (0);
1673 }
1674 return (EINVAL);
1675 }
1676
1677 static int
adabitsysctl(SYSCTL_HANDLER_ARGS)1678 adabitsysctl(SYSCTL_HANDLER_ARGS)
1679 {
1680 u_int *flags = arg1;
1681 u_int test = arg2;
1682 int tmpout, error;
1683
1684 tmpout = !!(*flags & test);
1685 error = SYSCTL_OUT(req, &tmpout, sizeof(tmpout));
1686 if (error || !req->newptr)
1687 return (error);
1688
1689 return (EPERM);
1690 }
1691
1692 static int
adaflagssysctl(SYSCTL_HANDLER_ARGS)1693 adaflagssysctl(SYSCTL_HANDLER_ARGS)
1694 {
1695 struct sbuf sbuf;
1696 struct ada_softc *softc = arg1;
1697 int error;
1698
1699 sbuf_new_for_sysctl(&sbuf, NULL, 0, req);
1700 if (softc->flags != 0)
1701 sbuf_printf(&sbuf, "0x%b", (unsigned)softc->flags, ADA_FLAG_STRING);
1702 else
1703 sbuf_putc(&sbuf, '0');
1704 error = sbuf_finish(&sbuf);
1705 sbuf_delete(&sbuf);
1706
1707 return (error);
1708 }
1709
1710 static void
adasetflags(struct ada_softc * softc,struct ccb_getdev * cgd)1711 adasetflags(struct ada_softc *softc, struct ccb_getdev *cgd)
1712 {
1713 if ((cgd->ident_data.capabilities1 & ATA_SUPPORT_DMA) &&
1714 (cgd->inq_flags & SID_DMA))
1715 softc->flags |= ADA_FLAG_CAN_DMA;
1716 else
1717 softc->flags &= ~ADA_FLAG_CAN_DMA;
1718
1719 if (cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) {
1720 softc->flags |= ADA_FLAG_CAN_48BIT;
1721 if (cgd->inq_flags & SID_DMA48)
1722 softc->flags |= ADA_FLAG_CAN_DMA48;
1723 else
1724 softc->flags &= ~ADA_FLAG_CAN_DMA48;
1725 } else
1726 softc->flags &= ~(ADA_FLAG_CAN_48BIT | ADA_FLAG_CAN_DMA48);
1727
1728 if (cgd->ident_data.support.command2 & ATA_SUPPORT_FLUSHCACHE)
1729 softc->flags |= ADA_FLAG_CAN_FLUSHCACHE;
1730 else
1731 softc->flags &= ~ADA_FLAG_CAN_FLUSHCACHE;
1732
1733 if (cgd->ident_data.support.command1 & ATA_SUPPORT_POWERMGT)
1734 softc->flags |= ADA_FLAG_CAN_POWERMGT;
1735 else
1736 softc->flags &= ~ADA_FLAG_CAN_POWERMGT;
1737
1738 if ((cgd->ident_data.satacapabilities & ATA_SUPPORT_NCQ) &&
1739 (cgd->inq_flags & SID_DMA) && (cgd->inq_flags & SID_CmdQue))
1740 softc->flags |= ADA_FLAG_CAN_NCQ;
1741 else
1742 softc->flags &= ~ADA_FLAG_CAN_NCQ;
1743
1744 if ((cgd->ident_data.support_dsm & ATA_SUPPORT_DSM_TRIM) &&
1745 (cgd->inq_flags & SID_DMA) &&
1746 (softc->quirks & ADA_Q_NO_TRIM) == 0) {
1747 softc->flags |= ADA_FLAG_CAN_TRIM;
1748 softc->trim_max_ranges = TRIM_MAX_RANGES;
1749 if (cgd->ident_data.max_dsm_blocks != 0) {
1750 softc->trim_max_ranges =
1751 min(cgd->ident_data.max_dsm_blocks *
1752 ATA_DSM_BLK_RANGES, softc->trim_max_ranges);
1753 }
1754 /*
1755 * If we can do RCVSND_FPDMA_QUEUED commands, we may be able
1756 * to do NCQ trims, if we support trims at all. We also need
1757 * support from the SIM to do things properly. Perhaps we
1758 * should look at log 13 dword 0 bit 0 and dword 1 bit 0 are
1759 * set too...
1760 */
1761 if ((softc->quirks & ADA_Q_NCQ_TRIM_BROKEN) == 0 &&
1762 (softc->flags & ADA_FLAG_PIM_ATA_EXT) != 0 &&
1763 (cgd->ident_data.satacapabilities2 &
1764 ATA_SUPPORT_RCVSND_FPDMA_QUEUED) != 0 &&
1765 (softc->flags & ADA_FLAG_CAN_TRIM) != 0)
1766 softc->flags |= ADA_FLAG_CAN_NCQ_TRIM;
1767 else
1768 softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
1769 } else
1770 softc->flags &= ~(ADA_FLAG_CAN_TRIM | ADA_FLAG_CAN_NCQ_TRIM);
1771
1772 if (cgd->ident_data.support.command2 & ATA_SUPPORT_CFA)
1773 softc->flags |= ADA_FLAG_CAN_CFA;
1774 else
1775 softc->flags &= ~ADA_FLAG_CAN_CFA;
1776
1777 /*
1778 * Now that we've set the appropriate flags, setup the delete
1779 * method.
1780 */
1781 adasetdeletemethod(softc);
1782
1783 if ((cgd->ident_data.support.extension & ATA_SUPPORT_GENLOG)
1784 && ((softc->quirks & ADA_Q_LOG_BROKEN) == 0))
1785 softc->flags |= ADA_FLAG_CAN_LOG;
1786 else
1787 softc->flags &= ~ADA_FLAG_CAN_LOG;
1788
1789 if ((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
1790 ATA_SUPPORT_ZONE_HOST_AWARE)
1791 softc->zone_mode = ADA_ZONE_HOST_AWARE;
1792 else if (((cgd->ident_data.support3 & ATA_SUPPORT_ZONE_MASK) ==
1793 ATA_SUPPORT_ZONE_DEV_MANAGED)
1794 || (softc->quirks & ADA_Q_SMR_DM))
1795 softc->zone_mode = ADA_ZONE_DRIVE_MANAGED;
1796 else
1797 softc->zone_mode = ADA_ZONE_NONE;
1798
1799 if (cgd->ident_data.support.command1 & ATA_SUPPORT_LOOKAHEAD)
1800 softc->flags |= ADA_FLAG_CAN_RAHEAD;
1801 else
1802 softc->flags &= ~ADA_FLAG_CAN_RAHEAD;
1803
1804 if (cgd->ident_data.support.command1 & ATA_SUPPORT_WRITECACHE)
1805 softc->flags |= ADA_FLAG_CAN_WCACHE;
1806 else
1807 softc->flags &= ~ADA_FLAG_CAN_WCACHE;
1808 }
1809
1810 static cam_status
adaregister(struct cam_periph * periph,void * arg)1811 adaregister(struct cam_periph *periph, void *arg)
1812 {
1813 struct ada_softc *softc;
1814 struct ccb_getdev *cgd;
1815 struct disk_params *dp;
1816 struct sbuf sb;
1817 char *announce_buf;
1818 caddr_t match;
1819 int quirks;
1820
1821 cgd = (struct ccb_getdev *)arg;
1822 if (cgd == NULL) {
1823 printf("adaregister: no getdev CCB, can't register device\n");
1824 return(CAM_REQ_CMP_ERR);
1825 }
1826
1827 softc = (struct ada_softc *)malloc(sizeof(*softc), M_DEVBUF,
1828 M_NOWAIT|M_ZERO);
1829
1830 if (softc == NULL) {
1831 printf("adaregister: Unable to probe new device. "
1832 "Unable to allocate softc\n");
1833 return(CAM_REQ_CMP_ERR);
1834 }
1835
1836 announce_buf = softc->announce_temp;
1837 bzero(announce_buf, ADA_ANNOUNCETMP_SZ);
1838
1839 periph->softc = softc;
1840 xpt_path_inq(&softc->cpi, periph->path);
1841
1842 /*
1843 * See if this device has any quirks.
1844 */
1845 match = cam_quirkmatch((caddr_t)&cgd->ident_data,
1846 (caddr_t)ada_quirk_table,
1847 nitems(ada_quirk_table),
1848 sizeof(*ada_quirk_table), ata_identify_match);
1849 if (match != NULL)
1850 softc->quirks = ((struct ada_quirk_entry *)match)->quirks;
1851 else
1852 softc->quirks = ADA_Q_NONE;
1853
1854 TASK_INIT(&softc->sysctl_task, 0, adasysctlinit, periph);
1855
1856 /*
1857 * Take a reference on the periph while adastart is called to finish
1858 * the probe. The reference will be dropped in adaprobedone at the
1859 * end of probe.
1860 */
1861 (void)cam_periph_acquire(periph);
1862 cam_periph_unlock(periph);
1863 snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
1864 "kern.cam.ada.%d.quirks", periph->unit_number);
1865 quirks = softc->quirks;
1866 TUNABLE_INT_FETCH(announce_buf, &quirks);
1867 softc->quirks = quirks;
1868 softc->read_ahead = -1;
1869 snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
1870 "kern.cam.ada.%d.read_ahead", periph->unit_number);
1871 TUNABLE_INT_FETCH(announce_buf, &softc->read_ahead);
1872 softc->write_cache = -1;
1873 snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
1874 "kern.cam.ada.%d.write_cache", periph->unit_number);
1875 TUNABLE_INT_FETCH(announce_buf, &softc->write_cache);
1876
1877 /*
1878 * Let XPT know we can use UMA-allocated CCBs.
1879 */
1880 if (ada_enable_uma_ccbs) {
1881 KASSERT(ada_ccb_zone != NULL,
1882 ("%s: NULL ada_ccb_zone", __func__));
1883 periph->ccb_zone = ada_ccb_zone;
1884 }
1885
1886 /*
1887 * Set support flags based on the Identify data and quirks.
1888 */
1889 adasetflags(softc, cgd);
1890 if (softc->cpi.hba_misc & PIM_ATA_EXT)
1891 softc->flags |= ADA_FLAG_PIM_ATA_EXT;
1892
1893 /* Disable queue sorting for non-rotational media by default. */
1894 if (cgd->ident_data.media_rotation_rate == ATA_RATE_NON_ROTATING) {
1895 softc->flags &= ~ADA_FLAG_ROTATING;
1896 } else {
1897 softc->flags |= ADA_FLAG_ROTATING;
1898 }
1899 softc->disk = disk_alloc();
1900 adasetgeom(softc, cgd);
1901 softc->disk->d_devstat = devstat_new_entry(periph->periph_name,
1902 periph->unit_number, softc->params.secsize,
1903 DEVSTAT_ALL_SUPPORTED,
1904 DEVSTAT_TYPE_DIRECT |
1905 XPORT_DEVSTAT_TYPE(softc->cpi.transport),
1906 DEVSTAT_PRIORITY_DISK);
1907 softc->disk->d_open = adaopen;
1908 softc->disk->d_close = adaclose;
1909 softc->disk->d_strategy = adastrategy;
1910 softc->disk->d_getattr = adagetattr;
1911 if (cam_sim_pollable(periph->sim))
1912 softc->disk->d_dump = adadump;
1913 softc->disk->d_gone = adadiskgonecb;
1914 softc->disk->d_name = "ada";
1915 softc->disk->d_drv1 = periph;
1916 softc->disk->d_unit = periph->unit_number;
1917
1918 if (cam_iosched_init(&softc->cam_iosched, periph, softc->disk,
1919 adaschedule) != 0) {
1920 printf("adaregister: Unable to probe new device. "
1921 "Unable to allocate iosched memory\n");
1922 free(softc, M_DEVBUF);
1923 return(CAM_REQ_CMP_ERR);
1924 }
1925 cam_iosched_set_sort_queue(softc->cam_iosched,
1926 (softc->flags & ADA_FLAG_ROTATING) ? -1 : 0);
1927
1928 cam_periph_lock(periph);
1929
1930 dp = &softc->params;
1931 snprintf(announce_buf, ADA_ANNOUNCETMP_SZ,
1932 "%juMB (%ju %u byte sectors)",
1933 ((uintmax_t)dp->secsize * dp->sectors) / (1024 * 1024),
1934 (uintmax_t)dp->sectors, dp->secsize);
1935
1936 sbuf_new(&sb, softc->announce_buffer, ADA_ANNOUNCE_SZ, SBUF_FIXEDLEN);
1937 xpt_announce_periph_sbuf(periph, &sb, announce_buf);
1938 xpt_announce_quirks_sbuf(periph, &sb, softc->quirks, ADA_Q_BIT_STRING);
1939 sbuf_finish(&sb);
1940 sbuf_putbuf(&sb);
1941
1942 /*
1943 * Create our sysctl variables, now that we know
1944 * we have successfully attached.
1945 */
1946 if (cam_periph_acquire(periph) == 0)
1947 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task);
1948
1949 /*
1950 * Add async callbacks for bus reset and
1951 * bus device reset calls. I don't bother
1952 * checking if this fails as, in most cases,
1953 * the system will function just fine without
1954 * them and the only alternative would be to
1955 * not attach the device on failure.
1956 */
1957 xpt_register_async(AC_SENT_BDR | AC_BUS_RESET | AC_LOST_DEVICE |
1958 AC_GETDEV_CHANGED | AC_ADVINFO_CHANGED,
1959 adaasync, periph, periph->path);
1960
1961 /*
1962 * Schedule a periodic event to occasionally send an
1963 * ordered tag to a device.
1964 */
1965 callout_init_mtx(&softc->sendordered_c, cam_periph_mtx(periph), 0);
1966 callout_reset_sbt(&softc->sendordered_c,
1967 SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
1968 adasendorderedtag, softc, C_PREL(1));
1969
1970 /* Released after probe when disk_create() call pass it to GEOM. */
1971 cam_periph_hold_boot(periph);
1972
1973 if (ADA_RA >= 0 && softc->flags & ADA_FLAG_CAN_RAHEAD) {
1974 softc->state = ADA_STATE_RAHEAD;
1975 } else if (ADA_WC >= 0 && softc->flags & ADA_FLAG_CAN_WCACHE) {
1976 softc->state = ADA_STATE_WCACHE;
1977 } else if ((softc->flags & ADA_FLAG_CAN_LOG)
1978 && (softc->zone_mode != ADA_ZONE_NONE)) {
1979 softc->state = ADA_STATE_LOGDIR;
1980 } else {
1981 /*
1982 * Nothing to probe, so we can just transition to the
1983 * normal state.
1984 */
1985 adaprobedone(periph, NULL);
1986 return(CAM_REQ_CMP);
1987 }
1988
1989 xpt_schedule(periph, CAM_PRIORITY_DEV);
1990 return(CAM_REQ_CMP);
1991 }
1992
1993 static int
ada_dsmtrim_req_create(struct ada_softc * softc,struct bio * bp,struct trim_request * req)1994 ada_dsmtrim_req_create(struct ada_softc *softc, struct bio *bp, struct trim_request *req)
1995 {
1996 uint64_t lastlba = (uint64_t)-1, lbas = 0;
1997 int c, lastcount = 0, off, ranges = 0;
1998
1999 bzero(req, sizeof(*req));
2000 TAILQ_INIT(&req->bps);
2001 do {
2002 uint64_t lba = bp->bio_pblkno;
2003 int count = bp->bio_bcount / softc->params.secsize;
2004
2005 /* Try to extend the previous range. */
2006 if (lba == lastlba) {
2007 c = min(count, ATA_DSM_RANGE_MAX - lastcount);
2008 lastcount += c;
2009 off = (ranges - 1) * ATA_DSM_RANGE_SIZE;
2010 req->data[off + 6] = lastcount & 0xff;
2011 req->data[off + 7] =
2012 (lastcount >> 8) & 0xff;
2013 count -= c;
2014 lba += c;
2015 lbas += c;
2016 }
2017
2018 while (count > 0) {
2019 c = min(count, ATA_DSM_RANGE_MAX);
2020 off = ranges * ATA_DSM_RANGE_SIZE;
2021 req->data[off + 0] = lba & 0xff;
2022 req->data[off + 1] = (lba >> 8) & 0xff;
2023 req->data[off + 2] = (lba >> 16) & 0xff;
2024 req->data[off + 3] = (lba >> 24) & 0xff;
2025 req->data[off + 4] = (lba >> 32) & 0xff;
2026 req->data[off + 5] = (lba >> 40) & 0xff;
2027 req->data[off + 6] = c & 0xff;
2028 req->data[off + 7] = (c >> 8) & 0xff;
2029 lba += c;
2030 lbas += c;
2031 count -= c;
2032 lastcount = c;
2033 ranges++;
2034 /*
2035 * Its the caller's responsibility to ensure the
2036 * request will fit so we don't need to check for
2037 * overrun here
2038 */
2039 }
2040 lastlba = lba;
2041 TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
2042
2043 bp = cam_iosched_next_trim(softc->cam_iosched);
2044 if (bp == NULL)
2045 break;
2046 if (bp->bio_bcount / softc->params.secsize >
2047 (softc->trim_max_ranges - ranges) * ATA_DSM_RANGE_MAX) {
2048 cam_iosched_put_back_trim(softc->cam_iosched, bp);
2049 break;
2050 }
2051 } while (1);
2052 softc->trim_count++;
2053 softc->trim_ranges += ranges;
2054 softc->trim_lbas += lbas;
2055
2056 return (ranges);
2057 }
2058
2059 static void
ada_dsmtrim(struct ada_softc * softc,struct bio * bp,struct ccb_ataio * ataio)2060 ada_dsmtrim(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
2061 {
2062 struct trim_request *req = &softc->trim_req;
2063 int ranges;
2064
2065 ranges = ada_dsmtrim_req_create(softc, bp, req);
2066 cam_fill_ataio(ataio,
2067 ada_retry_count,
2068 adadone,
2069 CAM_DIR_OUT,
2070 0,
2071 req->data,
2072 howmany(ranges, ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
2073 ada_default_timeout * 1000);
2074 ata_48bit_cmd(ataio, ATA_DATA_SET_MANAGEMENT,
2075 ATA_DSM_TRIM, 0, howmany(ranges, ATA_DSM_BLK_RANGES));
2076 }
2077
2078 static void
ada_ncq_dsmtrim(struct ada_softc * softc,struct bio * bp,struct ccb_ataio * ataio)2079 ada_ncq_dsmtrim(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
2080 {
2081 struct trim_request *req = &softc->trim_req;
2082 int ranges;
2083
2084 ranges = ada_dsmtrim_req_create(softc, bp, req);
2085 cam_fill_ataio(ataio,
2086 ada_retry_count,
2087 adadone,
2088 CAM_DIR_OUT,
2089 0,
2090 req->data,
2091 howmany(ranges, ATA_DSM_BLK_RANGES) * ATA_DSM_BLK_SIZE,
2092 ada_default_timeout * 1000);
2093 ata_ncq_cmd(ataio,
2094 ATA_SEND_FPDMA_QUEUED,
2095 0,
2096 howmany(ranges, ATA_DSM_BLK_RANGES));
2097 ataio->cmd.sector_count_exp = ATA_SFPDMA_DSM;
2098 ataio->ata_flags |= ATA_FLAG_AUX;
2099 ataio->aux = 1;
2100 }
2101
2102 static void
ada_cfaerase(struct ada_softc * softc,struct bio * bp,struct ccb_ataio * ataio)2103 ada_cfaerase(struct ada_softc *softc, struct bio *bp, struct ccb_ataio *ataio)
2104 {
2105 struct trim_request *req = &softc->trim_req;
2106 uint64_t lba = bp->bio_pblkno;
2107 uint16_t count = bp->bio_bcount / softc->params.secsize;
2108
2109 bzero(req, sizeof(*req));
2110 TAILQ_INIT(&req->bps);
2111 TAILQ_INSERT_TAIL(&req->bps, bp, bio_queue);
2112
2113 cam_fill_ataio(ataio,
2114 ada_retry_count,
2115 adadone,
2116 CAM_DIR_NONE,
2117 0,
2118 NULL,
2119 0,
2120 ada_default_timeout*1000);
2121
2122 if (count >= 256)
2123 count = 0;
2124 ata_28bit_cmd(ataio, ATA_CFA_ERASE, 0, lba, count);
2125 }
2126
2127 static int
ada_zone_bio_to_ata(int disk_zone_cmd)2128 ada_zone_bio_to_ata(int disk_zone_cmd)
2129 {
2130 switch (disk_zone_cmd) {
2131 case DISK_ZONE_OPEN:
2132 return ATA_ZM_OPEN_ZONE;
2133 case DISK_ZONE_CLOSE:
2134 return ATA_ZM_CLOSE_ZONE;
2135 case DISK_ZONE_FINISH:
2136 return ATA_ZM_FINISH_ZONE;
2137 case DISK_ZONE_RWP:
2138 return ATA_ZM_RWP;
2139 }
2140
2141 return -1;
2142 }
2143
2144 static int
ada_zone_cmd(struct cam_periph * periph,union ccb * ccb,struct bio * bp,int * queue_ccb)2145 ada_zone_cmd(struct cam_periph *periph, union ccb *ccb, struct bio *bp,
2146 int *queue_ccb)
2147 {
2148 struct ada_softc *softc;
2149 int error;
2150
2151 error = 0;
2152
2153 if (bp->bio_cmd != BIO_ZONE) {
2154 error = EINVAL;
2155 goto bailout;
2156 }
2157
2158 softc = periph->softc;
2159
2160 switch (bp->bio_zone.zone_cmd) {
2161 case DISK_ZONE_OPEN:
2162 case DISK_ZONE_CLOSE:
2163 case DISK_ZONE_FINISH:
2164 case DISK_ZONE_RWP: {
2165 int zone_flags;
2166 int zone_sa;
2167 uint64_t lba;
2168
2169 zone_sa = ada_zone_bio_to_ata(bp->bio_zone.zone_cmd);
2170 if (zone_sa == -1) {
2171 xpt_print(periph->path, "Cannot translate zone "
2172 "cmd %#x to ATA\n", bp->bio_zone.zone_cmd);
2173 error = EINVAL;
2174 goto bailout;
2175 }
2176
2177 zone_flags = 0;
2178 lba = bp->bio_zone.zone_params.rwp.id;
2179
2180 if (bp->bio_zone.zone_params.rwp.flags &
2181 DISK_ZONE_RWP_FLAG_ALL)
2182 zone_flags |= ZBC_OUT_ALL;
2183
2184 ata_zac_mgmt_out(&ccb->ataio,
2185 /*retries*/ ada_retry_count,
2186 /*cbfcnp*/ adadone,
2187 /*use_ncq*/ (softc->flags &
2188 ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
2189 /*zm_action*/ zone_sa,
2190 /*zone_id*/ lba,
2191 /*zone_flags*/ zone_flags,
2192 /*sector_count*/ 0,
2193 /*data_ptr*/ NULL,
2194 /*dxfer_len*/ 0,
2195 /*timeout*/ ada_default_timeout * 1000);
2196 *queue_ccb = 1;
2197
2198 break;
2199 }
2200 case DISK_ZONE_REPORT_ZONES: {
2201 uint8_t *rz_ptr;
2202 uint32_t num_entries, alloc_size;
2203 struct disk_zone_report *rep;
2204
2205 rep = &bp->bio_zone.zone_params.report;
2206
2207 num_entries = rep->entries_allocated;
2208 if (num_entries == 0) {
2209 xpt_print(periph->path, "No entries allocated for "
2210 "Report Zones request\n");
2211 error = EINVAL;
2212 goto bailout;
2213 }
2214 alloc_size = sizeof(struct scsi_report_zones_hdr) +
2215 (sizeof(struct scsi_report_zones_desc) * num_entries);
2216 alloc_size = min(alloc_size, softc->disk->d_maxsize);
2217 rz_ptr = malloc(alloc_size, M_ATADA, M_NOWAIT | M_ZERO);
2218 if (rz_ptr == NULL) {
2219 xpt_print(periph->path, "Unable to allocate memory "
2220 "for Report Zones request\n");
2221 error = ENOMEM;
2222 goto bailout;
2223 }
2224
2225 ata_zac_mgmt_in(&ccb->ataio,
2226 /*retries*/ ada_retry_count,
2227 /*cbcfnp*/ adadone,
2228 /*use_ncq*/ (softc->flags &
2229 ADA_FLAG_PIM_ATA_EXT) ? 1 : 0,
2230 /*zm_action*/ ATA_ZM_REPORT_ZONES,
2231 /*zone_id*/ rep->starting_id,
2232 /*zone_flags*/ rep->rep_options,
2233 /*data_ptr*/ rz_ptr,
2234 /*dxfer_len*/ alloc_size,
2235 /*timeout*/ ada_default_timeout * 1000);
2236
2237 /*
2238 * For BIO_ZONE, this isn't normally needed. However, it
2239 * is used by devstat_end_transaction_bio() to determine
2240 * how much data was transferred.
2241 */
2242 /*
2243 * XXX KDM we have a problem. But I'm not sure how to fix
2244 * it. devstat uses bio_bcount - bio_resid to calculate
2245 * the amount of data transferred. The GEOM disk code
2246 * uses bio_length - bio_resid to calculate the amount of
2247 * data in bio_completed. We have different structure
2248 * sizes above and below the ada(4) driver. So, if we
2249 * use the sizes above, the amount transferred won't be
2250 * quite accurate for devstat. If we use different sizes
2251 * for bio_bcount and bio_length (above and below
2252 * respectively), then the residual needs to match one or
2253 * the other. Everything is calculated after the bio
2254 * leaves the driver, so changing the values around isn't
2255 * really an option. For now, just set the count to the
2256 * passed in length. This means that the calculations
2257 * above (e.g. bio_completed) will be correct, but the
2258 * amount of data reported to devstat will be slightly
2259 * under or overstated.
2260 */
2261 bp->bio_bcount = bp->bio_length;
2262
2263 *queue_ccb = 1;
2264
2265 break;
2266 }
2267 case DISK_ZONE_GET_PARAMS: {
2268 struct disk_zone_disk_params *params;
2269
2270 params = &bp->bio_zone.zone_params.disk_params;
2271 bzero(params, sizeof(*params));
2272
2273 switch (softc->zone_mode) {
2274 case ADA_ZONE_DRIVE_MANAGED:
2275 params->zone_mode = DISK_ZONE_MODE_DRIVE_MANAGED;
2276 break;
2277 case ADA_ZONE_HOST_AWARE:
2278 params->zone_mode = DISK_ZONE_MODE_HOST_AWARE;
2279 break;
2280 case ADA_ZONE_HOST_MANAGED:
2281 params->zone_mode = DISK_ZONE_MODE_HOST_MANAGED;
2282 break;
2283 default:
2284 case ADA_ZONE_NONE:
2285 params->zone_mode = DISK_ZONE_MODE_NONE;
2286 break;
2287 }
2288
2289 if (softc->zone_flags & ADA_ZONE_FLAG_URSWRZ)
2290 params->flags |= DISK_ZONE_DISK_URSWRZ;
2291
2292 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_SEQ_SET) {
2293 params->optimal_seq_zones = softc->optimal_seq_zones;
2294 params->flags |= DISK_ZONE_OPT_SEQ_SET;
2295 }
2296
2297 if (softc->zone_flags & ADA_ZONE_FLAG_OPT_NONSEQ_SET) {
2298 params->optimal_nonseq_zones =
2299 softc->optimal_nonseq_zones;
2300 params->flags |= DISK_ZONE_OPT_NONSEQ_SET;
2301 }
2302
2303 if (softc->zone_flags & ADA_ZONE_FLAG_MAX_SEQ_SET) {
2304 params->max_seq_zones = softc->max_seq_zones;
2305 params->flags |= DISK_ZONE_MAX_SEQ_SET;
2306 }
2307 if (softc->zone_flags & ADA_ZONE_FLAG_RZ_SUP)
2308 params->flags |= DISK_ZONE_RZ_SUP;
2309
2310 if (softc->zone_flags & ADA_ZONE_FLAG_OPEN_SUP)
2311 params->flags |= DISK_ZONE_OPEN_SUP;
2312
2313 if (softc->zone_flags & ADA_ZONE_FLAG_CLOSE_SUP)
2314 params->flags |= DISK_ZONE_CLOSE_SUP;
2315
2316 if (softc->zone_flags & ADA_ZONE_FLAG_FINISH_SUP)
2317 params->flags |= DISK_ZONE_FINISH_SUP;
2318
2319 if (softc->zone_flags & ADA_ZONE_FLAG_RWP_SUP)
2320 params->flags |= DISK_ZONE_RWP_SUP;
2321 break;
2322 }
2323 default:
2324 break;
2325 }
2326 bailout:
2327 return (error);
2328 }
2329
2330 static void
adastart(struct cam_periph * periph,union ccb * start_ccb)2331 adastart(struct cam_periph *periph, union ccb *start_ccb)
2332 {
2333 struct ada_softc *softc = (struct ada_softc *)periph->softc;
2334 struct ccb_ataio *ataio = &start_ccb->ataio;
2335 uint32_t priority = start_ccb->ccb_h.pinfo.priority;
2336
2337 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("adastart\n"));
2338
2339 /*
2340 * When we're running the state machine, we should only accept DEV CCBs.
2341 * When we're doing normal I/O we should only accept NORMAL CCBs.
2342 *
2343 * While in the state machine, we carefully single step the queue, but
2344 * there's no protection for 'extra' calls to xpt_schedule() at the
2345 * wrong priority. Guard against that so that we filter any CCBs that
2346 * are offered at the wrong priority. This avoids generating requests
2347 * that are at normal priority.
2348 ` */
2349 if ((softc->state != ADA_STATE_NORMAL && priority != CAM_PRIORITY_DEV) ||
2350 (softc->state == ADA_STATE_NORMAL && priority != CAM_PRIORITY_NORMAL)) {
2351 xpt_print(periph->path, "Bad priority for state %d prio %d\n",
2352 softc->state, priority);
2353 xpt_release_ccb(start_ccb);
2354 return;
2355 }
2356
2357 switch (softc->state) {
2358 case ADA_STATE_NORMAL:
2359 {
2360 struct bio *bp;
2361 uint8_t tag_code;
2362
2363 KASSERT(priority == CAM_PRIORITY_NORMAL,
2364 ("Expected priority %d, found %d in state normal",
2365 CAM_PRIORITY_NORMAL, priority));
2366
2367 bp = cam_iosched_next_bio(softc->cam_iosched);
2368 if (bp == NULL) {
2369 xpt_release_ccb(start_ccb);
2370 break;
2371 }
2372
2373 if ((bp->bio_flags & BIO_ORDERED) != 0 ||
2374 (bp->bio_cmd != BIO_DELETE && (softc->flags & ADA_FLAG_NEED_OTAG) != 0)) {
2375 softc->flags &= ~ADA_FLAG_NEED_OTAG;
2376 softc->flags |= ADA_FLAG_WAS_OTAG;
2377 tag_code = 0;
2378 } else {
2379 tag_code = 1;
2380 }
2381 switch (bp->bio_cmd) {
2382 case BIO_WRITE:
2383 case BIO_READ:
2384 {
2385 uint64_t lba = bp->bio_pblkno;
2386 uint16_t count = bp->bio_bcount / softc->params.secsize;
2387 void *data_ptr;
2388 int rw_op;
2389
2390 if (bp->bio_cmd == BIO_WRITE) {
2391 softc->flags |= ADA_FLAG_DIRTY;
2392 rw_op = CAM_DIR_OUT;
2393 } else {
2394 rw_op = CAM_DIR_IN;
2395 }
2396
2397 data_ptr = bp->bio_data;
2398 if ((bp->bio_flags & (BIO_UNMAPPED|BIO_VLIST)) != 0) {
2399 rw_op |= CAM_DATA_BIO;
2400 data_ptr = bp;
2401 }
2402
2403 #ifdef CAM_TEST_FAILURE
2404 int fail = 0;
2405
2406 /*
2407 * Support the failure ioctls. If the command is a
2408 * read, and there are pending forced read errors, or
2409 * if a write and pending write errors, then fail this
2410 * operation with EIO. This is useful for testing
2411 * purposes. Also, support having every Nth read fail.
2412 *
2413 * This is a rather blunt tool.
2414 */
2415 if (bp->bio_cmd == BIO_READ) {
2416 if (softc->force_read_error) {
2417 softc->force_read_error--;
2418 fail = 1;
2419 }
2420 if (softc->periodic_read_error > 0) {
2421 if (++softc->periodic_read_count >=
2422 softc->periodic_read_error) {
2423 softc->periodic_read_count = 0;
2424 fail = 1;
2425 }
2426 }
2427 } else {
2428 if (softc->force_write_error) {
2429 softc->force_write_error--;
2430 fail = 1;
2431 }
2432 }
2433 if (fail) {
2434 biofinish(bp, NULL, EIO);
2435 xpt_release_ccb(start_ccb);
2436 adaschedule(periph);
2437 return;
2438 }
2439 #endif
2440 KASSERT((bp->bio_flags & BIO_UNMAPPED) == 0 ||
2441 round_page(bp->bio_bcount + bp->bio_ma_offset) /
2442 PAGE_SIZE == bp->bio_ma_n,
2443 ("Short bio %p", bp));
2444 cam_fill_ataio(ataio,
2445 ada_retry_count,
2446 adadone,
2447 rw_op,
2448 0,
2449 data_ptr,
2450 bp->bio_bcount,
2451 ada_default_timeout*1000);
2452
2453 if ((softc->flags & ADA_FLAG_CAN_NCQ) && tag_code) {
2454 if (bp->bio_cmd == BIO_READ) {
2455 ata_ncq_cmd(ataio, ATA_READ_FPDMA_QUEUED,
2456 lba, count);
2457 } else {
2458 ata_ncq_cmd(ataio, ATA_WRITE_FPDMA_QUEUED,
2459 lba, count);
2460 }
2461 } else if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
2462 (lba + count >= ATA_MAX_28BIT_LBA ||
2463 count > 256)) {
2464 if (softc->flags & ADA_FLAG_CAN_DMA48) {
2465 if (bp->bio_cmd == BIO_READ) {
2466 ata_48bit_cmd(ataio, ATA_READ_DMA48,
2467 0, lba, count);
2468 } else {
2469 ata_48bit_cmd(ataio, ATA_WRITE_DMA48,
2470 0, lba, count);
2471 }
2472 } else {
2473 if (bp->bio_cmd == BIO_READ) {
2474 ata_48bit_cmd(ataio, ATA_READ_MUL48,
2475 0, lba, count);
2476 } else {
2477 ata_48bit_cmd(ataio, ATA_WRITE_MUL48,
2478 0, lba, count);
2479 }
2480 }
2481 } else {
2482 if (count == 256)
2483 count = 0;
2484 if (softc->flags & ADA_FLAG_CAN_DMA) {
2485 if (bp->bio_cmd == BIO_READ) {
2486 ata_28bit_cmd(ataio, ATA_READ_DMA,
2487 0, lba, count);
2488 } else {
2489 ata_28bit_cmd(ataio, ATA_WRITE_DMA,
2490 0, lba, count);
2491 }
2492 } else {
2493 if (bp->bio_cmd == BIO_READ) {
2494 ata_28bit_cmd(ataio, ATA_READ_MUL,
2495 0, lba, count);
2496 } else {
2497 ata_28bit_cmd(ataio, ATA_WRITE_MUL,
2498 0, lba, count);
2499 }
2500 }
2501 }
2502 break;
2503 }
2504 case BIO_DELETE:
2505 switch (softc->delete_method) {
2506 case ADA_DELETE_NCQ_DSM_TRIM:
2507 ada_ncq_dsmtrim(softc, bp, ataio);
2508 break;
2509 case ADA_DELETE_DSM_TRIM:
2510 ada_dsmtrim(softc, bp, ataio);
2511 break;
2512 case ADA_DELETE_CFA_ERASE:
2513 ada_cfaerase(softc, bp, ataio);
2514 break;
2515 default:
2516 biofinish(bp, NULL, EOPNOTSUPP);
2517 xpt_release_ccb(start_ccb);
2518 adaschedule(periph);
2519 return;
2520 }
2521 start_ccb->ccb_h.ccb_state = ADA_CCB_TRIM;
2522 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
2523 cam_iosched_submit_trim(softc->cam_iosched);
2524 goto out;
2525 case BIO_FLUSH:
2526 cam_fill_ataio(ataio,
2527 1,
2528 adadone,
2529 CAM_DIR_NONE,
2530 0,
2531 NULL,
2532 0,
2533 ada_default_timeout*1000);
2534
2535 if (softc->flags & ADA_FLAG_CAN_48BIT)
2536 ata_48bit_cmd(ataio, ATA_FLUSHCACHE48, 0, 0, 0);
2537 else
2538 ata_28bit_cmd(ataio, ATA_FLUSHCACHE, 0, 0, 0);
2539 break;
2540 case BIO_ZONE: {
2541 int error, queue_ccb;
2542
2543 queue_ccb = 0;
2544
2545 error = ada_zone_cmd(periph, start_ccb, bp, &queue_ccb);
2546 if ((error != 0)
2547 || (queue_ccb == 0)) {
2548 /*
2549 * g_io_deliver will recurisvely call start
2550 * routine for ENOMEM, so drop the periph
2551 * lock to allow that recursion.
2552 */
2553 if (error == ENOMEM)
2554 cam_periph_unlock(periph);
2555 biofinish(bp, NULL, error);
2556 if (error == ENOMEM)
2557 cam_periph_lock(periph);
2558 xpt_release_ccb(start_ccb);
2559 return;
2560 }
2561 break;
2562 }
2563 default:
2564 biofinish(bp, NULL, EOPNOTSUPP);
2565 xpt_release_ccb(start_ccb);
2566 return;
2567 }
2568 start_ccb->ccb_h.ccb_state = ADA_CCB_BUFFER_IO;
2569 start_ccb->ccb_h.flags |= CAM_UNLOCKED;
2570 out:
2571 start_ccb->ccb_h.ccb_bp = bp;
2572 softc->outstanding_cmds++;
2573 softc->refcount++;
2574 cam_periph_unlock(periph);
2575 xpt_action(start_ccb);
2576 cam_periph_lock(periph);
2577
2578 /* May have more work to do, so ensure we stay scheduled */
2579 adaschedule(periph);
2580 break;
2581 }
2582 case ADA_STATE_RAHEAD:
2583 case ADA_STATE_WCACHE:
2584 {
2585 KASSERT(priority == CAM_PRIORITY_DEV,
2586 ("Expected priority %d, found %d in state %s",
2587 CAM_PRIORITY_DEV, priority,
2588 softc->state == ADA_STATE_RAHEAD ? "rahead" : "wcache"));
2589
2590 cam_fill_ataio(ataio,
2591 1,
2592 adadone,
2593 CAM_DIR_NONE,
2594 0,
2595 NULL,
2596 0,
2597 ada_default_timeout*1000);
2598
2599 if (softc->state == ADA_STATE_RAHEAD) {
2600 ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_RA ?
2601 ATA_SF_ENAB_RCACHE : ATA_SF_DIS_RCACHE, 0, 0);
2602 start_ccb->ccb_h.ccb_state = ADA_CCB_RAHEAD;
2603 } else {
2604 ata_28bit_cmd(ataio, ATA_SETFEATURES, ADA_WC ?
2605 ATA_SF_ENAB_WCACHE : ATA_SF_DIS_WCACHE, 0, 0);
2606 start_ccb->ccb_h.ccb_state = ADA_CCB_WCACHE;
2607 }
2608 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
2609 xpt_action(start_ccb);
2610 break;
2611 }
2612 case ADA_STATE_LOGDIR:
2613 {
2614 struct ata_gp_log_dir *log_dir;
2615
2616 KASSERT(priority == CAM_PRIORITY_DEV,
2617 ("Expected priority %d, found %d in state logdir",
2618 CAM_PRIORITY_DEV, priority));
2619
2620 if ((softc->flags & ADA_FLAG_CAN_LOG) == 0) {
2621 adaprobedone(periph, start_ccb);
2622 break;
2623 }
2624
2625 log_dir = malloc(sizeof(*log_dir), M_ATADA, M_NOWAIT|M_ZERO);
2626 if (log_dir == NULL) {
2627 xpt_print(periph->path, "Couldn't malloc log_dir "
2628 "data\n");
2629 softc->state = ADA_STATE_NORMAL;
2630 xpt_release_ccb(start_ccb);
2631 break;
2632 }
2633
2634 ata_read_log(ataio,
2635 /*retries*/1,
2636 /*cbfcnp*/adadone,
2637 /*log_address*/ ATA_LOG_DIRECTORY,
2638 /*page_number*/ 0,
2639 /*block_count*/ 1,
2640 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2641 CAM_ATAIO_DMA : 0,
2642 /*data_ptr*/ (uint8_t *)log_dir,
2643 /*dxfer_len*/sizeof(*log_dir),
2644 /*timeout*/ada_default_timeout*1000);
2645
2646 start_ccb->ccb_h.ccb_state = ADA_CCB_LOGDIR;
2647 xpt_action(start_ccb);
2648 break;
2649 }
2650 case ADA_STATE_IDDIR:
2651 {
2652 struct ata_identify_log_pages *id_dir;
2653
2654 KASSERT(priority == CAM_PRIORITY_DEV,
2655 ("Expected priority %d, found %d in state iddir",
2656 CAM_PRIORITY_DEV, priority));
2657
2658 id_dir = malloc(sizeof(*id_dir), M_ATADA, M_NOWAIT | M_ZERO);
2659 if (id_dir == NULL) {
2660 xpt_print(periph->path, "Couldn't malloc id_dir "
2661 "data\n");
2662 adaprobedone(periph, start_ccb);
2663 break;
2664 }
2665
2666 ata_read_log(ataio,
2667 /*retries*/1,
2668 /*cbfcnp*/adadone,
2669 /*log_address*/ ATA_IDENTIFY_DATA_LOG,
2670 /*page_number*/ ATA_IDL_PAGE_LIST,
2671 /*block_count*/ 1,
2672 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2673 CAM_ATAIO_DMA : 0,
2674 /*data_ptr*/ (uint8_t *)id_dir,
2675 /*dxfer_len*/ sizeof(*id_dir),
2676 /*timeout*/ada_default_timeout*1000);
2677
2678 start_ccb->ccb_h.ccb_state = ADA_CCB_IDDIR;
2679 xpt_action(start_ccb);
2680 break;
2681 }
2682 case ADA_STATE_SUP_CAP:
2683 {
2684 struct ata_identify_log_sup_cap *sup_cap;
2685
2686 KASSERT(priority == CAM_PRIORITY_DEV,
2687 ("Expected priority %d, found %d in state sup_cap",
2688 CAM_PRIORITY_DEV, priority));
2689
2690 sup_cap = malloc(sizeof(*sup_cap), M_ATADA, M_NOWAIT|M_ZERO);
2691 if (sup_cap == NULL) {
2692 xpt_print(periph->path, "Couldn't malloc sup_cap "
2693 "data\n");
2694 adaprobedone(periph, start_ccb);
2695 break;
2696 }
2697
2698 ata_read_log(ataio,
2699 /*retries*/1,
2700 /*cbfcnp*/adadone,
2701 /*log_address*/ ATA_IDENTIFY_DATA_LOG,
2702 /*page_number*/ ATA_IDL_SUP_CAP,
2703 /*block_count*/ 1,
2704 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2705 CAM_ATAIO_DMA : 0,
2706 /*data_ptr*/ (uint8_t *)sup_cap,
2707 /*dxfer_len*/ sizeof(*sup_cap),
2708 /*timeout*/ada_default_timeout*1000);
2709
2710 start_ccb->ccb_h.ccb_state = ADA_CCB_SUP_CAP;
2711 xpt_action(start_ccb);
2712 break;
2713 }
2714 case ADA_STATE_ZONE:
2715 {
2716 struct ata_zoned_info_log *ata_zone;
2717
2718 KASSERT(priority == CAM_PRIORITY_DEV,
2719 ("Expected priority %d, found %d in state zone",
2720 CAM_PRIORITY_DEV, priority));
2721
2722 ata_zone = malloc(sizeof(*ata_zone), M_ATADA, M_NOWAIT|M_ZERO);
2723 if (ata_zone == NULL) {
2724 xpt_print(periph->path, "Couldn't malloc ata_zone "
2725 "data\n");
2726 adaprobedone(periph, start_ccb);
2727 break;
2728 }
2729
2730 ata_read_log(ataio,
2731 /*retries*/1,
2732 /*cbfcnp*/adadone,
2733 /*log_address*/ ATA_IDENTIFY_DATA_LOG,
2734 /*page_number*/ ATA_IDL_ZDI,
2735 /*block_count*/ 1,
2736 /*protocol*/ softc->flags & ADA_FLAG_CAN_DMA ?
2737 CAM_ATAIO_DMA : 0,
2738 /*data_ptr*/ (uint8_t *)ata_zone,
2739 /*dxfer_len*/ sizeof(*ata_zone),
2740 /*timeout*/ada_default_timeout*1000);
2741
2742 start_ccb->ccb_h.ccb_state = ADA_CCB_ZONE;
2743 xpt_action(start_ccb);
2744 break;
2745 }
2746 }
2747 }
2748
2749 static void
adaprobedone(struct cam_periph * periph,union ccb * ccb)2750 adaprobedone(struct cam_periph *periph, union ccb *ccb)
2751 {
2752 struct ada_softc *softc;
2753
2754 softc = (struct ada_softc *)periph->softc;
2755
2756 /*
2757 * Since our peripheral may be invalidated by an error we must release
2758 * our CCB before releasing the reference on the peripheral. The
2759 * peripheral will only go away once the last reference is removed, and
2760 * we need it around for the CCB release operation.
2761 */
2762 if (ccb != NULL)
2763 xpt_release_ccb(ccb);
2764
2765 softc->state = ADA_STATE_NORMAL;
2766 softc->flags |= ADA_FLAG_PROBED;
2767 adaschedule(periph);
2768 if ((softc->flags & ADA_FLAG_ANNOUNCED) == 0) {
2769 softc->flags |= ADA_FLAG_ANNOUNCED;
2770
2771 /*
2772 * We'll release this reference once GEOM calls us back via
2773 * adadiskgonecb(), telling us that our provider has been freed.
2774 */
2775 if (cam_periph_acquire(periph) == 0)
2776 disk_create(softc->disk, DISK_VERSION);
2777
2778 cam_periph_release_boot(periph);
2779 }
2780 cam_periph_release_locked(periph);
2781 }
2782
2783 static void
adazonedone(struct cam_periph * periph,union ccb * ccb)2784 adazonedone(struct cam_periph *periph, union ccb *ccb)
2785 {
2786 struct bio *bp;
2787
2788 bp = (struct bio *)ccb->ccb_h.ccb_bp;
2789
2790 switch (bp->bio_zone.zone_cmd) {
2791 case DISK_ZONE_OPEN:
2792 case DISK_ZONE_CLOSE:
2793 case DISK_ZONE_FINISH:
2794 case DISK_ZONE_RWP:
2795 break;
2796 case DISK_ZONE_REPORT_ZONES: {
2797 uint32_t avail_len;
2798 struct disk_zone_report *rep;
2799 struct scsi_report_zones_hdr *hdr;
2800 struct scsi_report_zones_desc *desc;
2801 struct disk_zone_rep_entry *entry;
2802 uint32_t hdr_len, num_avail;
2803 uint32_t num_to_fill, i;
2804
2805 rep = &bp->bio_zone.zone_params.report;
2806 avail_len = ccb->ataio.dxfer_len - ccb->ataio.resid;
2807 /*
2808 * Note that bio_resid isn't normally used for zone
2809 * commands, but it is used by devstat_end_transaction_bio()
2810 * to determine how much data was transferred. Because
2811 * the size of the SCSI/ATA data structures is different
2812 * than the size of the BIO interface structures, the
2813 * amount of data actually transferred from the drive will
2814 * be different than the amount of data transferred to
2815 * the user.
2816 */
2817 hdr = (struct scsi_report_zones_hdr *)ccb->ataio.data_ptr;
2818 if (avail_len < sizeof(*hdr)) {
2819 /*
2820 * Is there a better error than EIO here? We asked
2821 * for at least the header, and we got less than
2822 * that.
2823 */
2824 bp->bio_error = EIO;
2825 bp->bio_flags |= BIO_ERROR;
2826 bp->bio_resid = bp->bio_bcount;
2827 break;
2828 }
2829
2830 hdr_len = le32dec(hdr->length);
2831 if (hdr_len > 0)
2832 rep->entries_available = hdr_len / sizeof(*desc);
2833 else
2834 rep->entries_available = 0;
2835 /*
2836 * NOTE: using the same values for the BIO version of the
2837 * same field as the SCSI/ATA values. This means we could
2838 * get some additional values that aren't defined in bio.h
2839 * if more values of the same field are defined later.
2840 */
2841 rep->header.same = hdr->byte4 & SRZ_SAME_MASK;
2842 rep->header.maximum_lba = le64dec(hdr->maximum_lba);
2843 /*
2844 * If the drive reports no entries that match the query,
2845 * we're done.
2846 */
2847 if (hdr_len == 0) {
2848 rep->entries_filled = 0;
2849 bp->bio_resid = bp->bio_bcount;
2850 break;
2851 }
2852
2853 num_avail = min((avail_len - sizeof(*hdr)) / sizeof(*desc),
2854 hdr_len / sizeof(*desc));
2855 /*
2856 * If the drive didn't return any data, then we're done.
2857 */
2858 if (num_avail == 0) {
2859 rep->entries_filled = 0;
2860 bp->bio_resid = bp->bio_bcount;
2861 break;
2862 }
2863
2864 num_to_fill = min(num_avail, rep->entries_allocated);
2865 /*
2866 * If the user didn't allocate any entries for us to fill,
2867 * we're done.
2868 */
2869 if (num_to_fill == 0) {
2870 rep->entries_filled = 0;
2871 bp->bio_resid = bp->bio_bcount;
2872 break;
2873 }
2874
2875 for (i = 0, desc = &hdr->desc_list[0], entry=&rep->entries[0];
2876 i < num_to_fill; i++, desc++, entry++) {
2877 /*
2878 * NOTE: we're mapping the values here directly
2879 * from the SCSI/ATA bit definitions to the bio.h
2880 * definitions. There is also a warning in
2881 * disk_zone.h, but the impact is that if
2882 * additional values are added in the SCSI/ATA
2883 * specs these will be visible to consumers of
2884 * this interface.
2885 */
2886 entry->zone_type = desc->zone_type & SRZ_TYPE_MASK;
2887 entry->zone_condition =
2888 (desc->zone_flags & SRZ_ZONE_COND_MASK) >>
2889 SRZ_ZONE_COND_SHIFT;
2890 entry->zone_flags |= desc->zone_flags &
2891 (SRZ_ZONE_NON_SEQ|SRZ_ZONE_RESET);
2892 entry->zone_length = le64dec(desc->zone_length);
2893 entry->zone_start_lba = le64dec(desc->zone_start_lba);
2894 entry->write_pointer_lba =
2895 le64dec(desc->write_pointer_lba);
2896 }
2897 rep->entries_filled = num_to_fill;
2898 /*
2899 * Note that this residual is accurate from the user's
2900 * standpoint, but the amount transferred isn't accurate
2901 * from the standpoint of what actually came back from the
2902 * drive.
2903 */
2904 bp->bio_resid = bp->bio_bcount - (num_to_fill * sizeof(*entry));
2905 break;
2906 }
2907 case DISK_ZONE_GET_PARAMS:
2908 default:
2909 /*
2910 * In theory we should not get a GET_PARAMS bio, since it
2911 * should be handled without queueing the command to the
2912 * drive.
2913 */
2914 panic("%s: Invalid zone command %d", __func__,
2915 bp->bio_zone.zone_cmd);
2916 break;
2917 }
2918
2919 if (bp->bio_zone.zone_cmd == DISK_ZONE_REPORT_ZONES)
2920 free(ccb->ataio.data_ptr, M_ATADA);
2921 }
2922
2923 static void
adadone(struct cam_periph * periph,union ccb * done_ccb)2924 adadone(struct cam_periph *periph, union ccb *done_ccb)
2925 {
2926 struct ada_softc *softc;
2927 struct ccb_ataio *ataio;
2928 struct cam_path *path;
2929 uint32_t priority;
2930 int state;
2931
2932 softc = (struct ada_softc *)periph->softc;
2933 ataio = &done_ccb->ataio;
2934 path = done_ccb->ccb_h.path;
2935 priority = done_ccb->ccb_h.pinfo.priority;
2936
2937 CAM_DEBUG(path, CAM_DEBUG_TRACE, ("adadone\n"));
2938
2939 state = ataio->ccb_h.ccb_state & ADA_CCB_TYPE_MASK;
2940 switch (state) {
2941 case ADA_CCB_BUFFER_IO:
2942 case ADA_CCB_TRIM:
2943 {
2944 struct bio *bp;
2945 int error;
2946
2947 KASSERT(priority == CAM_PRIORITY_NORMAL,
2948 ("Expected priority %d, found %d for normal I/O",
2949 CAM_PRIORITY_NORMAL, priority));
2950
2951 cam_periph_lock(periph);
2952 bp = (struct bio *)done_ccb->ccb_h.ccb_bp;
2953 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
2954 error = adaerror(done_ccb, CAM_RETRY_SELTO, 0);
2955 if (error == ERESTART) {
2956 /* A retry was scheduled, so just return. */
2957 cam_periph_unlock(periph);
2958 return;
2959 }
2960 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2961 cam_release_devq(path,
2962 /*relsim_flags*/0,
2963 /*reduction*/0,
2964 /*timeout*/0,
2965 /*getcount_only*/0);
2966 /*
2967 * If we get an error on an NCQ DSM TRIM, fall back
2968 * to a non-NCQ DSM TRIM forever. Please note that if
2969 * CAN_NCQ_TRIM is set, CAN_TRIM is necessarily set too.
2970 * However, for this one trim, we treat it as advisory
2971 * and return success up the stack.
2972 */
2973 if (state == ADA_CCB_TRIM &&
2974 error != 0 &&
2975 (softc->flags & ADA_FLAG_CAN_NCQ_TRIM) != 0) {
2976 softc->flags &= ~ADA_FLAG_CAN_NCQ_TRIM;
2977 error = 0;
2978 adasetdeletemethod(softc);
2979 }
2980 } else {
2981 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
2982 panic("REQ_CMP with QFRZN");
2983
2984 error = 0;
2985 }
2986 bp->bio_error = error;
2987 if (error != 0) {
2988 bp->bio_resid = bp->bio_bcount;
2989 bp->bio_flags |= BIO_ERROR;
2990 } else {
2991 if (bp->bio_cmd == BIO_ZONE)
2992 adazonedone(periph, done_ccb);
2993 else if (state == ADA_CCB_TRIM)
2994 bp->bio_resid = 0;
2995 else
2996 bp->bio_resid = ataio->resid;
2997
2998 if ((bp->bio_resid > 0)
2999 && (bp->bio_cmd != BIO_ZONE))
3000 bp->bio_flags |= BIO_ERROR;
3001 }
3002 softc->outstanding_cmds--;
3003 if (softc->outstanding_cmds == 0)
3004 softc->flags |= ADA_FLAG_WAS_OTAG;
3005
3006 /*
3007 * We need to call cam_iosched before we call biodone so that we
3008 * don't measure any activity that happens in the completion
3009 * routine, which in the case of sendfile can be quite
3010 * extensive. Release the periph refcount taken in adastart()
3011 * for each CCB.
3012 */
3013 cam_iosched_bio_complete(softc->cam_iosched, bp, done_ccb);
3014 xpt_release_ccb(done_ccb);
3015 KASSERT(softc->refcount >= 1, ("adadone softc %p refcount %d", softc, softc->refcount));
3016 softc->refcount--;
3017 if (state == ADA_CCB_TRIM) {
3018 TAILQ_HEAD(, bio) queue;
3019 struct bio *bp1;
3020
3021 TAILQ_INIT(&queue);
3022 TAILQ_CONCAT(&queue, &softc->trim_req.bps, bio_queue);
3023 /*
3024 * Normally, the xpt_release_ccb() above would make sure
3025 * that when we have more work to do, that work would
3026 * get kicked off. However, we specifically keep
3027 * trim_running set to 0 before the call above to allow
3028 * other I/O to progress when many BIO_DELETE requests
3029 * are pushed down. We set trim_running to 0 and call
3030 * daschedule again so that we don't stall if there are
3031 * no other I/Os pending apart from BIO_DELETEs.
3032 */
3033 cam_iosched_trim_done(softc->cam_iosched);
3034 adaschedule(periph);
3035 cam_periph_unlock(periph);
3036 while ((bp1 = TAILQ_FIRST(&queue)) != NULL) {
3037 TAILQ_REMOVE(&queue, bp1, bio_queue);
3038 bp1->bio_error = error;
3039 if (error != 0) {
3040 bp1->bio_flags |= BIO_ERROR;
3041 bp1->bio_resid = bp1->bio_bcount;
3042 } else
3043 bp1->bio_resid = 0;
3044 biodone(bp1);
3045 }
3046 } else {
3047 adaschedule(periph);
3048 cam_periph_unlock(periph);
3049 biodone(bp);
3050 }
3051 return;
3052 }
3053 case ADA_CCB_RAHEAD:
3054 {
3055 KASSERT(priority == CAM_PRIORITY_DEV,
3056 ("Expected priority %d, found %d in ccb state rahead",
3057 CAM_PRIORITY_DEV, priority));
3058
3059 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3060 if (adaerror(done_ccb, 0, 0) == ERESTART) {
3061 /* Drop freeze taken due to CAM_DEV_QFREEZE */
3062 cam_release_devq(path, 0, 0, 0, FALSE);
3063 return;
3064 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3065 cam_release_devq(path,
3066 /*relsim_flags*/0,
3067 /*reduction*/0,
3068 /*timeout*/0,
3069 /*getcount_only*/0);
3070 }
3071 }
3072
3073 xpt_release_ccb(done_ccb);
3074 softc->state = ADA_STATE_WCACHE;
3075 xpt_schedule(periph, priority);
3076 /* Drop freeze taken due to CAM_DEV_QFREEZE */
3077 cam_release_devq(path, 0, 0, 0, FALSE);
3078 return;
3079 }
3080 case ADA_CCB_WCACHE:
3081 {
3082 KASSERT(priority == CAM_PRIORITY_DEV,
3083 ("Expected priority %d, found %d in ccb state wcache",
3084 CAM_PRIORITY_DEV, priority));
3085
3086 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
3087 if (adaerror(done_ccb, 0, 0) == ERESTART) {
3088 /* Drop freeze taken due to CAM_DEV_QFREEZE */
3089 cam_release_devq(path, 0, 0, 0, FALSE);
3090 return;
3091 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
3092 cam_release_devq(path,
3093 /*relsim_flags*/0,
3094 /*reduction*/0,
3095 /*timeout*/0,
3096 /*getcount_only*/0);
3097 }
3098 }
3099
3100 /* Drop freeze taken due to CAM_DEV_QFREEZE */
3101 cam_release_devq(path, 0, 0, 0, FALSE);
3102
3103 if ((softc->flags & ADA_FLAG_CAN_LOG)
3104 && (softc->zone_mode != ADA_ZONE_NONE)) {
3105 xpt_release_ccb(done_ccb);
3106 softc->state = ADA_STATE_LOGDIR;
3107 xpt_schedule(periph, priority);
3108 } else {
3109 adaprobedone(periph, done_ccb);
3110 }
3111 return;
3112 }
3113 case ADA_CCB_LOGDIR:
3114 {
3115 int error;
3116
3117 KASSERT(priority == CAM_PRIORITY_DEV,
3118 ("Expected priority %d, found %d in ccb state logdir",
3119 CAM_PRIORITY_DEV, priority));
3120
3121 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3122 error = 0;
3123 softc->valid_logdir_len = 0;
3124 bzero(&softc->ata_logdir, sizeof(softc->ata_logdir));
3125 softc->valid_logdir_len =
3126 ataio->dxfer_len - ataio->resid;
3127 if (softc->valid_logdir_len > 0)
3128 bcopy(ataio->data_ptr, &softc->ata_logdir,
3129 min(softc->valid_logdir_len,
3130 sizeof(softc->ata_logdir)));
3131 /*
3132 * Figure out whether the Identify Device log is
3133 * supported. The General Purpose log directory
3134 * has a header, and lists the number of pages
3135 * available for each GP log identified by the
3136 * offset into the list.
3137 */
3138 if ((softc->valid_logdir_len >=
3139 ((ATA_IDENTIFY_DATA_LOG + 1) * sizeof(uint16_t)))
3140 && (le16dec(softc->ata_logdir.header) ==
3141 ATA_GP_LOG_DIR_VERSION)
3142 && (le16dec(&softc->ata_logdir.num_pages[
3143 (ATA_IDENTIFY_DATA_LOG *
3144 sizeof(uint16_t)) - sizeof(uint16_t)]) > 0)){
3145 softc->flags |= ADA_FLAG_CAN_IDLOG;
3146 } else {
3147 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
3148 }
3149 } else {
3150 error = adaerror(done_ccb, CAM_RETRY_SELTO,
3151 SF_RETRY_UA|SF_NO_PRINT);
3152 if (error == ERESTART)
3153 return;
3154 else if (error != 0) {
3155 /*
3156 * If we can't get the ATA log directory,
3157 * then ATA logs are effectively not
3158 * supported even if the bit is set in the
3159 * identify data.
3160 */
3161 softc->flags &= ~(ADA_FLAG_CAN_LOG |
3162 ADA_FLAG_CAN_IDLOG);
3163 if ((done_ccb->ccb_h.status &
3164 CAM_DEV_QFRZN) != 0) {
3165 /* Don't wedge this device's queue */
3166 cam_release_devq(done_ccb->ccb_h.path,
3167 /*relsim_flags*/0,
3168 /*reduction*/0,
3169 /*timeout*/0,
3170 /*getcount_only*/0);
3171 }
3172 }
3173 }
3174
3175 free(ataio->data_ptr, M_ATADA);
3176
3177 if ((error == 0)
3178 && (softc->flags & ADA_FLAG_CAN_IDLOG)) {
3179 softc->state = ADA_STATE_IDDIR;
3180 xpt_release_ccb(done_ccb);
3181 xpt_schedule(periph, priority);
3182 } else
3183 adaprobedone(periph, done_ccb);
3184
3185 return;
3186 }
3187 case ADA_CCB_IDDIR: {
3188 int error;
3189
3190 KASSERT(priority == CAM_PRIORITY_DEV,
3191 ("Expected priority %d, found %d in ccb state iddir",
3192 CAM_PRIORITY_DEV, priority));
3193
3194 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3195 off_t entries_offset, max_entries;
3196 error = 0;
3197
3198 softc->valid_iddir_len = 0;
3199 bzero(&softc->ata_iddir, sizeof(softc->ata_iddir));
3200 softc->flags &= ~(ADA_FLAG_CAN_SUPCAP |
3201 ADA_FLAG_CAN_ZONE);
3202 softc->valid_iddir_len =
3203 ataio->dxfer_len - ataio->resid;
3204 if (softc->valid_iddir_len > 0)
3205 bcopy(ataio->data_ptr, &softc->ata_iddir,
3206 min(softc->valid_iddir_len,
3207 sizeof(softc->ata_iddir)));
3208
3209 entries_offset =
3210 __offsetof(struct ata_identify_log_pages,entries);
3211 max_entries = softc->valid_iddir_len - entries_offset;
3212 if ((softc->valid_iddir_len > (entries_offset + 1))
3213 && (le64dec(softc->ata_iddir.header) ==
3214 ATA_IDLOG_REVISION)
3215 && (softc->ata_iddir.entry_count > 0)) {
3216 int num_entries, i;
3217
3218 num_entries = softc->ata_iddir.entry_count;
3219 num_entries = min(num_entries,
3220 softc->valid_iddir_len - entries_offset);
3221 for (i = 0; i < num_entries &&
3222 i < max_entries; i++) {
3223 if (softc->ata_iddir.entries[i] ==
3224 ATA_IDL_SUP_CAP)
3225 softc->flags |=
3226 ADA_FLAG_CAN_SUPCAP;
3227 else if (softc->ata_iddir.entries[i]==
3228 ATA_IDL_ZDI)
3229 softc->flags |=
3230 ADA_FLAG_CAN_ZONE;
3231
3232 if ((softc->flags &
3233 ADA_FLAG_CAN_SUPCAP)
3234 && (softc->flags &
3235 ADA_FLAG_CAN_ZONE))
3236 break;
3237 }
3238 }
3239 } else {
3240 error = adaerror(done_ccb, CAM_RETRY_SELTO,
3241 SF_RETRY_UA|SF_NO_PRINT);
3242 if (error == ERESTART)
3243 return;
3244 else if (error != 0) {
3245 /*
3246 * If we can't get the ATA Identify Data log
3247 * directory, then it effectively isn't
3248 * supported even if the ATA Log directory
3249 * a non-zero number of pages present for
3250 * this log.
3251 */
3252 softc->flags &= ~ADA_FLAG_CAN_IDLOG;
3253 if ((done_ccb->ccb_h.status &
3254 CAM_DEV_QFRZN) != 0) {
3255 /* Don't wedge this device's queue */
3256 cam_release_devq(done_ccb->ccb_h.path,
3257 /*relsim_flags*/0,
3258 /*reduction*/0,
3259 /*timeout*/0,
3260 /*getcount_only*/0);
3261 }
3262 }
3263 }
3264
3265 free(ataio->data_ptr, M_ATADA);
3266
3267 if ((error == 0)
3268 && (softc->flags & ADA_FLAG_CAN_SUPCAP)) {
3269 softc->state = ADA_STATE_SUP_CAP;
3270 xpt_release_ccb(done_ccb);
3271 xpt_schedule(periph, priority);
3272 } else
3273 adaprobedone(periph, done_ccb);
3274 return;
3275 }
3276 case ADA_CCB_SUP_CAP: {
3277 int error;
3278
3279 KASSERT(priority == CAM_PRIORITY_DEV,
3280 ("Expected priority %d, found %d in ccb state sup_cap",
3281 CAM_PRIORITY_DEV, priority));
3282
3283 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3284 uint32_t valid_len;
3285 size_t needed_size;
3286 struct ata_identify_log_sup_cap *sup_cap;
3287 error = 0;
3288
3289 sup_cap = (struct ata_identify_log_sup_cap *)
3290 ataio->data_ptr;
3291 valid_len = ataio->dxfer_len - ataio->resid;
3292 needed_size =
3293 __offsetof(struct ata_identify_log_sup_cap,
3294 sup_zac_cap) + 1 + sizeof(sup_cap->sup_zac_cap);
3295 if (valid_len >= needed_size) {
3296 uint64_t zoned, zac_cap;
3297
3298 zoned = le64dec(sup_cap->zoned_cap);
3299 if (zoned & ATA_ZONED_VALID) {
3300 /*
3301 * This should have already been
3302 * set, because this is also in the
3303 * ATA identify data.
3304 */
3305 if ((zoned & ATA_ZONED_MASK) ==
3306 ATA_SUPPORT_ZONE_HOST_AWARE)
3307 softc->zone_mode =
3308 ADA_ZONE_HOST_AWARE;
3309 else if ((zoned & ATA_ZONED_MASK) ==
3310 ATA_SUPPORT_ZONE_DEV_MANAGED)
3311 softc->zone_mode =
3312 ADA_ZONE_DRIVE_MANAGED;
3313 }
3314
3315 zac_cap = le64dec(sup_cap->sup_zac_cap);
3316 if (zac_cap & ATA_SUP_ZAC_CAP_VALID) {
3317 if (zac_cap & ATA_REPORT_ZONES_SUP)
3318 softc->zone_flags |=
3319 ADA_ZONE_FLAG_RZ_SUP;
3320 if (zac_cap & ATA_ND_OPEN_ZONE_SUP)
3321 softc->zone_flags |=
3322 ADA_ZONE_FLAG_OPEN_SUP;
3323 if (zac_cap & ATA_ND_CLOSE_ZONE_SUP)
3324 softc->zone_flags |=
3325 ADA_ZONE_FLAG_CLOSE_SUP;
3326 if (zac_cap & ATA_ND_FINISH_ZONE_SUP)
3327 softc->zone_flags |=
3328 ADA_ZONE_FLAG_FINISH_SUP;
3329 if (zac_cap & ATA_ND_RWP_SUP)
3330 softc->zone_flags |=
3331 ADA_ZONE_FLAG_RWP_SUP;
3332 } else {
3333 /*
3334 * This field was introduced in
3335 * ACS-4, r08 on April 28th, 2015.
3336 * If the drive firmware was written
3337 * to an earlier spec, it won't have
3338 * the field. So, assume all
3339 * commands are supported.
3340 */
3341 softc->zone_flags |=
3342 ADA_ZONE_FLAG_SUP_MASK;
3343 }
3344 }
3345 } else {
3346 error = adaerror(done_ccb, CAM_RETRY_SELTO,
3347 SF_RETRY_UA|SF_NO_PRINT);
3348 if (error == ERESTART)
3349 return;
3350 else if (error != 0) {
3351 /*
3352 * If we can't get the ATA Identify Data
3353 * Supported Capabilities page, clear the
3354 * flag...
3355 */
3356 softc->flags &= ~ADA_FLAG_CAN_SUPCAP;
3357 /*
3358 * And clear zone capabilities.
3359 */
3360 softc->zone_flags &= ~ADA_ZONE_FLAG_SUP_MASK;
3361 if ((done_ccb->ccb_h.status &
3362 CAM_DEV_QFRZN) != 0) {
3363 /* Don't wedge this device's queue */
3364 cam_release_devq(done_ccb->ccb_h.path,
3365 /*relsim_flags*/0,
3366 /*reduction*/0,
3367 /*timeout*/0,
3368 /*getcount_only*/0);
3369 }
3370 }
3371 }
3372
3373 free(ataio->data_ptr, M_ATADA);
3374
3375 if ((error == 0)
3376 && (softc->flags & ADA_FLAG_CAN_ZONE)) {
3377 softc->state = ADA_STATE_ZONE;
3378 xpt_release_ccb(done_ccb);
3379 xpt_schedule(periph, priority);
3380 } else
3381 adaprobedone(periph, done_ccb);
3382 return;
3383 }
3384 case ADA_CCB_ZONE: {
3385 int error;
3386
3387 KASSERT(priority == CAM_PRIORITY_DEV,
3388 ("Expected priority %d, found %d in ccb state zone",
3389 CAM_PRIORITY_DEV, priority));
3390
3391 if ((ataio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
3392 struct ata_zoned_info_log *zi_log;
3393 uint32_t valid_len;
3394 size_t needed_size;
3395
3396 zi_log = (struct ata_zoned_info_log *)ataio->data_ptr;
3397
3398 valid_len = ataio->dxfer_len - ataio->resid;
3399 needed_size = __offsetof(struct ata_zoned_info_log,
3400 version_info) + 1 + sizeof(zi_log->version_info);
3401 if (valid_len >= needed_size) {
3402 uint64_t tmpvar;
3403
3404 tmpvar = le64dec(zi_log->zoned_cap);
3405 if (tmpvar & ATA_ZDI_CAP_VALID) {
3406 if (tmpvar & ATA_ZDI_CAP_URSWRZ)
3407 softc->zone_flags |=
3408 ADA_ZONE_FLAG_URSWRZ;
3409 else
3410 softc->zone_flags &=
3411 ~ADA_ZONE_FLAG_URSWRZ;
3412 }
3413 tmpvar = le64dec(zi_log->optimal_seq_zones);
3414 if (tmpvar & ATA_ZDI_OPT_SEQ_VALID) {
3415 softc->zone_flags |=
3416 ADA_ZONE_FLAG_OPT_SEQ_SET;
3417 softc->optimal_seq_zones = (tmpvar &
3418 ATA_ZDI_OPT_SEQ_MASK);
3419 } else {
3420 softc->zone_flags &=
3421 ~ADA_ZONE_FLAG_OPT_SEQ_SET;
3422 softc->optimal_seq_zones = 0;
3423 }
3424
3425 tmpvar =le64dec(zi_log->optimal_nonseq_zones);
3426 if (tmpvar & ATA_ZDI_OPT_NS_VALID) {
3427 softc->zone_flags |=
3428 ADA_ZONE_FLAG_OPT_NONSEQ_SET;
3429 softc->optimal_nonseq_zones =
3430 (tmpvar & ATA_ZDI_OPT_NS_MASK);
3431 } else {
3432 softc->zone_flags &=
3433 ~ADA_ZONE_FLAG_OPT_NONSEQ_SET;
3434 softc->optimal_nonseq_zones = 0;
3435 }
3436
3437 tmpvar = le64dec(zi_log->max_seq_req_zones);
3438 if (tmpvar & ATA_ZDI_MAX_SEQ_VALID) {
3439 softc->zone_flags |=
3440 ADA_ZONE_FLAG_MAX_SEQ_SET;
3441 softc->max_seq_zones =
3442 (tmpvar & ATA_ZDI_MAX_SEQ_MASK);
3443 } else {
3444 softc->zone_flags &=
3445 ~ADA_ZONE_FLAG_MAX_SEQ_SET;
3446 softc->max_seq_zones = 0;
3447 }
3448 }
3449 } else {
3450 error = adaerror(done_ccb, CAM_RETRY_SELTO,
3451 SF_RETRY_UA|SF_NO_PRINT);
3452 if (error == ERESTART)
3453 return;
3454 else if (error != 0) {
3455 softc->flags &= ~ADA_FLAG_CAN_ZONE;
3456 softc->flags &= ~ADA_ZONE_FLAG_SET_MASK;
3457
3458 if ((done_ccb->ccb_h.status &
3459 CAM_DEV_QFRZN) != 0) {
3460 /* Don't wedge this device's queue */
3461 cam_release_devq(done_ccb->ccb_h.path,
3462 /*relsim_flags*/0,
3463 /*reduction*/0,
3464 /*timeout*/0,
3465 /*getcount_only*/0);
3466 }
3467 }
3468 }
3469 free(ataio->data_ptr, M_ATADA);
3470
3471 adaprobedone(periph, done_ccb);
3472 return;
3473 }
3474 case ADA_CCB_DUMP:
3475 /* No-op. We're polling */
3476 return;
3477 default:
3478 break;
3479 }
3480 xpt_release_ccb(done_ccb);
3481 }
3482
3483 static int
adaerror(union ccb * ccb,uint32_t cam_flags,uint32_t sense_flags)3484 adaerror(union ccb *ccb, uint32_t cam_flags, uint32_t sense_flags)
3485 {
3486 int error;
3487
3488 CAM_PROBE3(ada, error, ccb, cam_flags, sense_flags);
3489
3490 #ifdef CAM_IO_STATS
3491 struct ada_softc *softc;
3492 struct cam_periph *periph;
3493
3494 periph = xpt_path_periph(ccb->ccb_h.path);
3495 softc = (struct ada_softc *)periph->softc;
3496
3497 switch (ccb->ccb_h.status & CAM_STATUS_MASK) {
3498 case CAM_CMD_TIMEOUT:
3499 softc->timeouts++;
3500 break;
3501 case CAM_REQ_ABORTED:
3502 case CAM_REQ_CMP_ERR:
3503 case CAM_REQ_TERMIO:
3504 case CAM_UNREC_HBA_ERROR:
3505 case CAM_DATA_RUN_ERR:
3506 case CAM_ATA_STATUS_ERROR:
3507 softc->errors++;
3508 break;
3509 default:
3510 break;
3511 }
3512 #endif
3513
3514 error = cam_periph_error(ccb, cam_flags, sense_flags);
3515 CAM_PROBE2(ada, recovery, ccb, error);
3516 return (error);
3517 }
3518
3519 static void
adasetgeom(struct ada_softc * softc,struct ccb_getdev * cgd)3520 adasetgeom(struct ada_softc *softc, struct ccb_getdev *cgd)
3521 {
3522 struct disk_params *dp = &softc->params;
3523 uint64_t lbasize48;
3524 uint32_t lbasize;
3525 u_int maxio, d_flags;
3526 size_t tmpsize;
3527
3528 dp->secsize = ata_logical_sector_size(&cgd->ident_data);
3529 if ((cgd->ident_data.atavalid & ATA_FLAG_54_58) &&
3530 cgd->ident_data.current_heads != 0 &&
3531 cgd->ident_data.current_sectors != 0) {
3532 dp->heads = cgd->ident_data.current_heads;
3533 dp->secs_per_track = cgd->ident_data.current_sectors;
3534 dp->cylinders = cgd->ident_data.cylinders;
3535 dp->sectors = (uint32_t)cgd->ident_data.current_size_1 |
3536 ((uint32_t)cgd->ident_data.current_size_2 << 16);
3537 } else {
3538 dp->heads = cgd->ident_data.heads;
3539 dp->secs_per_track = cgd->ident_data.sectors;
3540 dp->cylinders = cgd->ident_data.cylinders;
3541 dp->sectors = cgd->ident_data.cylinders *
3542 (uint32_t)(dp->heads * dp->secs_per_track);
3543 }
3544 lbasize = (uint32_t)cgd->ident_data.lba_size_1 |
3545 ((uint32_t)cgd->ident_data.lba_size_2 << 16);
3546
3547 /* use the 28bit LBA size if valid or bigger than the CHS mapping */
3548 if (cgd->ident_data.cylinders == 16383 || dp->sectors < lbasize)
3549 dp->sectors = lbasize;
3550
3551 /* use the 48bit LBA size if valid */
3552 lbasize48 = ((uint64_t)cgd->ident_data.lba_size48_1) |
3553 ((uint64_t)cgd->ident_data.lba_size48_2 << 16) |
3554 ((uint64_t)cgd->ident_data.lba_size48_3 << 32) |
3555 ((uint64_t)cgd->ident_data.lba_size48_4 << 48);
3556 if ((cgd->ident_data.support.command2 & ATA_SUPPORT_ADDRESS48) &&
3557 lbasize48 > ATA_MAX_28BIT_LBA)
3558 dp->sectors = lbasize48;
3559
3560 maxio = softc->cpi.maxio; /* Honor max I/O size of SIM */
3561 if (maxio == 0)
3562 maxio = DFLTPHYS; /* traditional default */
3563 else if (maxio > maxphys)
3564 maxio = maxphys; /* for safety */
3565 if (softc->flags & ADA_FLAG_CAN_48BIT)
3566 maxio = min(maxio, 65536 * softc->params.secsize);
3567 else /* 28bit ATA command limit */
3568 maxio = min(maxio, 256 * softc->params.secsize);
3569 if (softc->quirks & ADA_Q_128KB)
3570 maxio = min(maxio, 128 * 1024);
3571 softc->disk->d_maxsize = maxio;
3572 d_flags = DISKFLAG_DIRECT_COMPLETION | DISKFLAG_CANZONE;
3573 if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE)
3574 d_flags |= DISKFLAG_CANFLUSHCACHE;
3575 if (softc->flags & ADA_FLAG_CAN_TRIM) {
3576 d_flags |= DISKFLAG_CANDELETE;
3577 softc->disk->d_delmaxsize = softc->params.secsize *
3578 ATA_DSM_RANGE_MAX * softc->trim_max_ranges;
3579 } else if ((softc->flags & ADA_FLAG_CAN_CFA) &&
3580 !(softc->flags & ADA_FLAG_CAN_48BIT)) {
3581 d_flags |= DISKFLAG_CANDELETE;
3582 softc->disk->d_delmaxsize = 256 * softc->params.secsize;
3583 } else
3584 softc->disk->d_delmaxsize = maxio;
3585 if ((softc->cpi.hba_misc & PIM_UNMAPPED) != 0) {
3586 d_flags |= DISKFLAG_UNMAPPED_BIO;
3587 softc->flags |= ADA_FLAG_UNMAPPEDIO;
3588 }
3589 softc->disk->d_flags = d_flags;
3590
3591 /*
3592 * ata_param_fixup will strip trailing padding spaces and add a NUL,
3593 * but if the field has no padding (as is common for serial numbers)
3594 * there will still be no NUL terminator. We cannot use strlcpy, since
3595 * it keeps reading src until it finds a NUL in order to compute the
3596 * return value (and will truncate the final character due to having a
3597 * single dsize rather than separate ssize and dsize), and strncpy does
3598 * not add a NUL to the destination if it reaches the character limit.
3599 */
3600 tmpsize = MIN(sizeof(softc->disk->d_descr) - 1,
3601 sizeof(cgd->ident_data.model));
3602 memcpy(softc->disk->d_descr, cgd->ident_data.model, tmpsize);
3603 softc->disk->d_descr[tmpsize] = '\0';
3604
3605 tmpsize = MIN(sizeof(softc->disk->d_ident) - 1,
3606 sizeof(cgd->ident_data.serial));
3607 memcpy(softc->disk->d_ident, cgd->ident_data.serial, tmpsize);
3608 softc->disk->d_ident[tmpsize] = '\0';
3609
3610 softc->disk->d_sectorsize = softc->params.secsize;
3611 softc->disk->d_mediasize = (off_t)softc->params.sectors *
3612 softc->params.secsize;
3613 if (ata_physical_sector_size(&cgd->ident_data) !=
3614 softc->params.secsize) {
3615 softc->disk->d_stripesize =
3616 ata_physical_sector_size(&cgd->ident_data);
3617 softc->disk->d_stripeoffset = (softc->disk->d_stripesize -
3618 ata_logical_sector_offset(&cgd->ident_data)) %
3619 softc->disk->d_stripesize;
3620 } else if (softc->quirks & ADA_Q_4K) {
3621 softc->disk->d_stripesize = 4096;
3622 softc->disk->d_stripeoffset = 0;
3623 }
3624 softc->disk->d_fwsectors = softc->params.secs_per_track;
3625 softc->disk->d_fwheads = softc->params.heads;
3626 softc->disk->d_rotation_rate = cgd->ident_data.media_rotation_rate;
3627 snprintf(softc->disk->d_attachment, sizeof(softc->disk->d_attachment),
3628 "%s%d", softc->cpi.dev_name, softc->cpi.unit_number);
3629 }
3630
3631 static void
adasendorderedtag(void * arg)3632 adasendorderedtag(void *arg)
3633 {
3634 struct ada_softc *softc = arg;
3635
3636 if (ada_send_ordered) {
3637 if (softc->outstanding_cmds > 0) {
3638 if ((softc->flags & ADA_FLAG_WAS_OTAG) == 0)
3639 softc->flags |= ADA_FLAG_NEED_OTAG;
3640 softc->flags &= ~ADA_FLAG_WAS_OTAG;
3641 }
3642 }
3643
3644 /* Queue us up again */
3645 callout_schedule_sbt(&softc->sendordered_c,
3646 SBT_1S / ADA_ORDEREDTAG_INTERVAL * ada_default_timeout, 0,
3647 C_PREL(1));
3648 }
3649
3650 /*
3651 * Step through all ADA peripheral drivers, and if the device is still open,
3652 * sync the disk cache to physical media.
3653 */
3654 static void
adaflush(void)3655 adaflush(void)
3656 {
3657 struct cam_periph *periph;
3658 struct ada_softc *softc;
3659 union ccb *ccb;
3660 int error;
3661
3662 CAM_PERIPH_FOREACH(periph, &adadriver) {
3663 softc = (struct ada_softc *)periph->softc;
3664 if (SCHEDULER_STOPPED()) {
3665 /* If we panicked with the lock held, do not recurse. */
3666 if (!cam_periph_owned(periph) &&
3667 (softc->flags & ADA_FLAG_OPEN)) {
3668 adadump(softc->disk, NULL, 0, 0);
3669 }
3670 continue;
3671 }
3672 cam_periph_lock(periph);
3673 /*
3674 * We only sync the cache if the drive is still open, and
3675 * if the drive is capable of it..
3676 */
3677 if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
3678 (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
3679 cam_periph_unlock(periph);
3680 continue;
3681 }
3682
3683 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
3684 cam_fill_ataio(&ccb->ataio,
3685 0,
3686 NULL,
3687 CAM_DIR_NONE,
3688 0,
3689 NULL,
3690 0,
3691 ada_default_timeout*1000);
3692 if (softc->flags & ADA_FLAG_CAN_48BIT)
3693 ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
3694 else
3695 ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
3696
3697 error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
3698 /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
3699 softc->disk->d_devstat);
3700 if (error != 0)
3701 xpt_print(periph->path, "Synchronize cache failed\n");
3702 xpt_release_ccb(ccb);
3703 cam_periph_unlock(periph);
3704 }
3705 }
3706
3707 static void
adaspindown(uint8_t cmd,int flags)3708 adaspindown(uint8_t cmd, int flags)
3709 {
3710 struct cam_periph *periph;
3711 struct ada_softc *softc;
3712 struct ccb_ataio local_ccb;
3713 int error;
3714 int mode;
3715
3716 CAM_PERIPH_FOREACH(periph, &adadriver) {
3717 /* If we panicked with lock held - not recurse here. */
3718 if (cam_periph_owned(periph))
3719 continue;
3720 cam_periph_lock(periph);
3721 softc = (struct ada_softc *)periph->softc;
3722 /*
3723 * We only spin-down the drive if it is capable of it..
3724 */
3725 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
3726 cam_periph_unlock(periph);
3727 continue;
3728 }
3729
3730 /*
3731 * Additionally check if we would spin up the drive instead of
3732 * spinning it down.
3733 */
3734 if (cmd == ATA_IDLE_IMMEDIATE) {
3735 memset(&local_ccb, 0, sizeof(local_ccb));
3736 xpt_setup_ccb(&local_ccb.ccb_h, periph->path,
3737 CAM_PRIORITY_NORMAL);
3738 local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
3739
3740 cam_fill_ataio(&local_ccb, 0, NULL, CAM_DIR_NONE,
3741 0, NULL, 0, ada_default_timeout * 1000);
3742 ata_28bit_cmd(&local_ccb, ATA_CHECK_POWER_MODE,
3743 0, 0, 0);
3744 local_ccb.cmd.flags |= CAM_ATAIO_NEEDRESULT;
3745
3746 error = cam_periph_runccb((union ccb *)&local_ccb,
3747 adaerror, /*cam_flags*/0,
3748 /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
3749 softc->disk->d_devstat);
3750 if (error != 0) {
3751 xpt_print(periph->path,
3752 "Failed to read current power mode\n");
3753 } else {
3754 mode = local_ccb.res.sector_count;
3755 #ifdef DIAGNOSTIC
3756 if (bootverbose) {
3757 xpt_print(periph->path,
3758 "disk power mode 0x%02x\n", mode);
3759 }
3760 #endif
3761 switch (mode) {
3762 case ATA_PM_STANDBY:
3763 case ATA_PM_STANDBY_Y:
3764 if (bootverbose) {
3765 xpt_print(periph->path,
3766 "already spun down\n");
3767 }
3768 cam_periph_unlock(periph);
3769 continue;
3770 default:
3771 break;
3772 }
3773 }
3774 }
3775
3776 if (bootverbose)
3777 xpt_print(periph->path, "spin-down\n");
3778
3779 memset(&local_ccb, 0, sizeof(local_ccb));
3780 xpt_setup_ccb(&local_ccb.ccb_h, periph->path, CAM_PRIORITY_NORMAL);
3781 local_ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
3782
3783 cam_fill_ataio(&local_ccb,
3784 0,
3785 NULL,
3786 CAM_DIR_NONE | flags,
3787 0,
3788 NULL,
3789 0,
3790 ada_default_timeout*1000);
3791 ata_28bit_cmd(&local_ccb, cmd, 0, 0, 0);
3792 error = cam_periph_runccb((union ccb *)&local_ccb, adaerror,
3793 /*cam_flags*/0, /*sense_flags*/ SF_NO_RECOVERY | SF_NO_RETRY,
3794 softc->disk->d_devstat);
3795 if (error != 0)
3796 xpt_print(periph->path, "Spin-down disk failed\n");
3797 cam_periph_unlock(periph);
3798 }
3799 }
3800
3801 static void
adashutdown(void * arg,int howto)3802 adashutdown(void *arg, int howto)
3803 {
3804 int how;
3805
3806 if ((howto & RB_NOSYNC) != 0)
3807 return;
3808
3809 adaflush();
3810
3811 /*
3812 * STANDBY IMMEDIATE saves any volatile data to the drive. It also spins
3813 * down hard drives. IDLE IMMEDIATE also saves the volatile data without
3814 * a spindown. We send the former when we expect to lose power soon. For
3815 * a warm boot, we send the latter to avoid a thundering herd of spinups
3816 * just after the kernel loads while probing. We have to do something to
3817 * flush the data because the BIOS in many systems resets the HBA
3818 * causing a COMINIT/COMRESET negotiation, which some drives interpret
3819 * as license to toss the volatile data, and others count as unclean
3820 * shutdown when in the Active PM state in SMART attributes.
3821 *
3822 * adaspindown will ensure that we don't send this to a drive that
3823 * doesn't support it.
3824 */
3825 if (ada_spindown_shutdown != 0) {
3826 how = (howto & (RB_HALT | RB_POWEROFF | RB_POWERCYCLE)) ?
3827 ATA_STANDBY_IMMEDIATE : ATA_IDLE_IMMEDIATE;
3828 adaspindown(how, 0);
3829 }
3830 }
3831
3832 static void
adasuspend(void * arg,enum power_stype stype)3833 adasuspend(void *arg, enum power_stype stype)
3834 {
3835
3836 adaflush();
3837 /*
3838 * SLEEP also fushes any volatile data, like STANDBY IMEDIATE,
3839 * so we don't need to send it as well.
3840 */
3841 if (ada_spindown_suspend != 0)
3842 adaspindown(ATA_SLEEP, CAM_DEV_QFREEZE);
3843 }
3844
3845 static void
adaresume(void * arg,enum power_stype stype)3846 adaresume(void *arg, enum power_stype stype)
3847 {
3848 struct cam_periph *periph;
3849 struct ada_softc *softc;
3850
3851 if (ada_spindown_suspend == 0)
3852 return;
3853
3854 CAM_PERIPH_FOREACH(periph, &adadriver) {
3855 cam_periph_lock(periph);
3856 softc = (struct ada_softc *)periph->softc;
3857 /*
3858 * We only spin-down the drive if it is capable of it..
3859 */
3860 if ((softc->flags & ADA_FLAG_CAN_POWERMGT) == 0) {
3861 cam_periph_unlock(periph);
3862 continue;
3863 }
3864
3865 if (bootverbose)
3866 xpt_print(periph->path, "resume\n");
3867
3868 /*
3869 * Drop freeze taken due to CAM_DEV_QFREEZE flag set on
3870 * sleep request.
3871 */
3872 cam_release_devq(periph->path,
3873 /*relsim_flags*/0,
3874 /*openings*/0,
3875 /*timeout*/0,
3876 /*getcount_only*/0);
3877
3878 cam_periph_unlock(periph);
3879 }
3880 }
3881
3882 #endif /* _KERNEL */
3883