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