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