1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SATA_H
#define _SATA_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Generic SATA Host Adapter Implementation
*/
#include <sys/types.h>
#include <sys/scsi/scsi.h>
#include <sys/scsi/impl/services.h>
#include <sys/sata/sata_defs.h>
#include <sys/sata/sata_hba.h>
/* Common flags specifying current state of a port or an attached drive. */
#define SATA_STATE_PROBING 0x000001
#define SATA_STATE_PROBED 0x000002
/* Statistics counters */
struct sata_port_stats {
uint64_t link_lost; /* event counter */
uint64_t link_established; /* event counter */
uint64_t device_attached; /* event counter */
uint64_t device_detached; /* event counter */
uint64_t port_reset; /* event counter */
uint64_t port_pwr_changed; /* event counter */
};
typedef struct sata_port_stats sata_port_stats_t;
struct sata_drive_stats {
uint64_t media_error; /* available ??? */
uint64_t drive_reset; /* event counter */
} sata_drv_stats_t;
typedef struct sata_drive_stats sata_drive_stats_t;
struct sata_ctrl_stats {
uint64_t ctrl_reset; /* event counter */
uint64_t ctrl_pwr_change; /* event counter */
};
typedef struct sata_ctrl_stats sata_ctrl_stats_t;
/*
* SATA HBA instance info structure
*/
struct sata_hba_inst {
dev_info_t *satahba_dip; /* this HBA instance devinfo */
struct sata_hba_inst *satahba_next; /* ptr to next sata_hba_inst */
struct sata_hba_inst *satahba_prev; /* ptr to prev sata_hba_inst */
struct scsi_hba_tran *satahba_scsi_tran; /* scsi_hba_tran */
struct sata_hba_tran *satahba_tran; /* sata_hba_tran */
kmutex_t satahba_mutex; /* sata hba cntrl mutex */
struct taskq *satahba_taskq; /* cmd completion task queue */
/*
* HBA event flags:
* SATA_EVNT_MAIN
* SATA_EVNT_PWR_LEVEL_CHANGED
* SATA_EVNT_SKIP
*/
uint_t satahba_event_flags;
struct sata_cport_info *satahba_dev_port[SATA_MAX_CPORTS];
/*
* DEVCTL open flag:
* SATA_DEVCTL_SOPENED
* SATA_DEVCTL_EXOPENED
*/
uint_t satahba_open_flag; /* shared open flag */
struct sata_ctrl_stats satahba_stats; /* HBA cntrl statistics */
uint_t satahba_attached; /* HBA attaching: */
/* 0 - not completed */
/* 1 - completed */
};
typedef struct sata_hba_inst sata_hba_inst_t;
/*
* SATA controller's device port info and state.
* This structure is pointed to by the sata_hba_inst.satahba_dev_port[x]
* where x is a device port number.
* cport_state holds port state flags, defined in sata_hba.h file.
* cport_event_flags holds SATA_EVNT_* flags defined in this file and in
* sata_hba.h file.
* cport_dev_type holds SATA_DTYPE_* types defined in sata_hba.h file.
*/
struct sata_cport_info {
sata_address_t cport_addr; /* this port SATA address */
kmutex_t cport_mutex; /* port mutex */
/*
* Port state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_PWRON
* SATA_PSTATE_PWROFF
* SATA_PSTATE_SHUTDOWN
* SATA_PSTATE_FAILED
*/
uint32_t cport_state;
/*
* Port event flags:
* SATA_EVNT_DEVICE_ATTACHED
* SATA_EVNT_DEVICE_DETACHED
* SATA_EVNT_LINK_LOST
* SATA_EVNT_LINK_ESTABLISHED
* SATA_EVNT_PORT_FAILED
* SATA_EVNT_PWR_LEVEL_CHANGED
*/
uint32_t cport_event_flags;
struct sata_port_scr cport_scr; /* Port status and ctrl regs */
/*
* Attached device type:
* SATA_DTYPE_NONE
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPITAPE
* SATA_DTYPE_ATAPIDISK
* SATA_DTYPE_PMULT
* SATA_DTYPE_UNKNOWN
* SATA_DTYPE_ATAPIPROC
*/
uint32_t cport_dev_type;
union {
struct sata_drive_info *cport_sata_drive; /* Attached drive info */
struct sata_pmult_info *cport_sata_pmult; /* Attached Port Mult */
} cport_devp;
/* lbolt value at link lost */
clock_t cport_link_lost_time;
/* lbolt value @ dev attached */
clock_t cport_dev_attach_time;
struct sata_port_stats cport_stats; /* Port statistics */
boolean_t cport_tgtnode_clean; /* Target node usable */
};
typedef struct sata_cport_info sata_cport_info_t;
/*
* Attached SATA drive info and state.
* This structure is pointed to by sata_cport_info's cport_sata_drive field
* when a drive is attached directly to a controller device port.
*/
struct sata_drive_info {
sata_address_t satadrv_addr; /* this drive SATA address */
/*
* Drive state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_DSTATE_PWR_ACTIVE
* SATA_DSTATE_PWR_IDLE
* SATA_DSTATE_RESET
* SATA_DSTATE_FAILED
*/
uint32_t satadrv_state;
/*
* drive event flags:
* SATA_EVNT_DRIVE_RESET
*/
uint32_t satadrv_event_flags;
/*
* lbolt value @ start of
* device reset processing
*/
clock_t satadrv_reset_time;
/*
* Attached device type:
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPITAPE
* SATA_DTYPE_ATAPIDISK
* SATA_DTYPE_ATAPIPROC
*/
uint32_t satadrv_type;
uint32_t satadrv_status_reg; /* drive status reg */
uint32_t satadrv_error_reg; /* drive error reg */
uint16_t satadrv_features_support; /* drive features support */
uint16_t satadrv_queue_depth; /* drive queue depth */
uint16_t satadrv_atapi_cdb_len; /* atapi supported cdb length */
uint16_t satadrv_atapi_trans_ver; /* atapi transport version */
uint16_t satadrv_settings; /* drive settings flags */
uint16_t satadrv_features_enabled; /* drive features enabled */
uint64_t satadrv_capacity; /* drive capacity */
uint64_t satadrv_max_queue_depth; /* maximum queue depth */
sata_id_t satadrv_id; /* Device Identify Data */
struct sata_drive_stats satadrv_stats; /* drive statistics */
/*
* saved standby timer
* [0] - [3] = high - low
*/
uint8_t satadrv_standby_timer[4];
uint8_t satadrv_power_level; /* saved power level */
};
typedef struct sata_drive_info sata_drive_info_t;
_NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_drive_info))
/* Port Multiplier & host port info and state */
struct sata_pmult_info {
sata_address_t pmult_addr; /* this PMult SATA Address */
/*
* PMult state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_FAILED
*/
uint32_t pmult_state;
uint32_t pmult_event_flags; /* Undefined for now */
struct sata_pmult_gscr pmult_gscr; /* PMult GSCR block */
uint32_t pmult_num_dev_ports; /* Number of data ports */
struct sata_pmport_info *pmult_dev_port[SATA_MAX_PMPORTS - 1];
};
typedef struct sata_pmult_info sata_pmult_info_t;
_NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_pmult_info))
_NOTE(MUTEX_PROTECTS_DATA(sata_cport_info::cport_mutex, \
sata_pmult_info::pmult_dev_port))
/* Port Multiplier's device port info & state */
struct sata_pmport_info {
sata_address_t pmport_addr; /* this SATA port address */
kmutex_t pmport_mutex; /* pmult device port mutex */
/*
* Port state flags
* SATA_STATE_UNKNOWN
* SATA_STATE_PROBING
* SATA_STATE_PROBED
* SATA_STATE_READY
* SATA_PSTATE_PWRON
* SATA_PSTATE_PWROFF
* SATA_PSTATE_SHUTDOWN
* SATA_PSTATE_FAILED
*/
uint32_t pmport_state;
/*
* Port event flags:
* SATA_EVNT_DEVICE_ATTACHED
* SATA_EVNT_DEVICE_DETACHED
* SATA_EVNT_LINK_LOST
* SATA_EVNT_LINK_ESTABLISHED
* SATA_EVNT_PORT_FAILED
* SATA_EVNT_PWR_LEVEL_CHANGED
*/
uint32_t pmport_event_flags;
struct sata_port_scr pmport_scr; /* PMult device port scr */
/*
* Attached device type:
* SATA_DTYPE_NONE
* SATA_DTYPE_ATADISK
* SATA_DTYPE_ATAPICD
* SATA_DTYPE_ATAPITAPE
* SATA_DTYPE_ATAPIDISK
* SATA_DTYPE_UNKNOWN
* SATA_DTYPE_ATAPIPROC
*/
uint32_t pmport_dev_type;
struct sata_drive_info *pmport_sata_drive; /* Attached drive info */
/* lbolt value at link lost */
clock_t pmport_link_lost_time;
/* lbolt value @ dev attached */
clock_t pmport_dev_attach_time;
struct sata_port_stats pmport_stats; /* Port statistics */
boolean_t pmport_tgtnode_clean; /* Target node usable */
};
typedef struct sata_pmport_info sata_pmport_info_t;
/*
* sata drive's power level
* default value is active
*/
#define SATA_POWER_ACTIVE 0x00
#define SATA_POWER_IDLE 0x01
#define SATA_POWER_STANDBY 0x02
#define SATA_POWER_STOPPED 0x03
/*
* pm-capable value definition according to PSARC 2009/310
*/
#define SATA_CAP_POWER_CONDITON PM_CAPABLE_SPC4
#define SATA_CAP_SMART_PAGE PM_CAPABLE_SMART_LOG
#define SATA_CAP_LOG_SENSE PM_CAPABLE_LOG_SUPPORTED
/*
* Port SSTATUS register (sata_port_scr sport_sstatus field).
* Link bits are valid only in port active state.
*/
#define SATA_PORT_DEVLINK_UP 0x00000103 /* Link with dev established */
#define SATA_PORT_DEVLINK_UP_MASK 0x0000010F /* Mask for link bits */
/*
* Port state clear mask (cport_state and pmport_state fields).
* SATA_PSTATE_SHUTDOWN and power state are preserved.
*/
#define SATA_PORT_STATE_CLEAR_MASK (~(SATA_PSTATE_SHUTDOWN))
/*
* Valid i.e.supported device types mask (cport_dev_type, satadrv_type,
* pmult_dev_type fields).
* ATA disks and ATAPI CD/DVD now.
*/
#define SATA_VALID_DEV_TYPE (SATA_DTYPE_ATADISK | \
SATA_DTYPE_ATAPICD | \
SATA_DTYPE_ATAPITAPE | \
SATA_DTYPE_ATAPIDISK)
/*
* Device feature_support (satadrv_features_support)
*/
#define SATA_DEV_F_DMA 0x01
#define SATA_DEV_F_LBA28 0x02
#define SATA_DEV_F_LBA48 0x04
#define SATA_DEV_F_NCQ 0x08
#define SATA_DEV_F_SATA1 0x10
#define SATA_DEV_F_SATA2 0x20
#define SATA_DEV_F_TCQ 0x40 /* Non NCQ tagged queuing */
#define SATA_DEV_F_SATA3 0x80
/*
* Device features enabled (satadrv_features_enabled)
*/
#define SATA_DEV_F_E_TAGGED_QING 0x01 /* Tagged queuing enabled */
#define SATA_DEV_F_E_UNTAGGED_QING 0x02 /* Untagged queuing enabled */
/*
* Drive settings flags (satdrv_settings)
*/
#define SATA_DEV_READ_AHEAD 0x0001 /* Read Ahead enabled */
#define SATA_DEV_WRITE_CACHE 0x0002 /* Write cache ON */
#define SATA_DEV_DMA 0x0004 /* DMA selected */
#define SATA_DEV_SERIAL_FEATURES 0x8000 /* Serial ATA feat. enabled */
#define SATA_DEV_ASYNCH_NOTIFY 0x2000 /* Asynch-event enabled */
#define SATA_DEV_RMSN 0x0100 /* Rem Media Stat Notfc enbl */
/*
* Internal event and flags.
* These flags are set in the *_event_flags fields of various structures.
* Events and lock flags defined below are used internally by the
* SATA framework (they are not reported by SATA HBA drivers).
*/
#define SATA_EVNT_MAIN 0x80000000
#define SATA_EVNT_SKIP 0x40000000
#define SATA_EVNT_INPROC_DEVICE_RESET 0x08000000
#define SATA_EVNT_CLEAR_DEVICE_RESET 0x04000000
#define SATA_EVNT_TARGET_NODE_CLEANUP 0x00000100
#define SATA_EVNT_AUTOONLINE_DEVICE 0x00000200
/*
* Lock flags - used to serialize configuration operations
* on ports and devices.
* SATA_EVNT_LOCK_PORT_BUSY is set by event daemon to prevent
* simultaneous cfgadm operations.
* SATA_APCTL_LOCK_PORT_BUSY is set by cfgadm ioctls to prevent
* simultaneous event processing.
*/
#define SATA_EVNT_LOCK_PORT_BUSY 0x00800000
#define SATA_APCTL_LOCK_PORT_BUSY 0x00400000
/* Mask for port events */
#define SATA_EVNT_PORT_EVENTS (SATA_EVNT_DEVICE_ATTACHED | \
SATA_EVNT_DEVICE_DETACHED | \
SATA_EVNT_LINK_LOST | \
SATA_EVNT_LINK_ESTABLISHED | \
SATA_EVNT_PMULT_LINK_CHANGED | \
SATA_EVNT_PORT_FAILED | \
SATA_EVNT_TARGET_NODE_CLEANUP | \
SATA_EVNT_AUTOONLINE_DEVICE)
/* Mask for drive events */
#define SATA_EVNT_DRIVE_EVENTS (SATA_EVNT_DEVICE_RESET | \
SATA_EVNT_INPROC_DEVICE_RESET)
#define SATA_EVNT_CONTROLLER_EVENTS SATA_EVNT_PWR_LEVEL_CHANGED
/* Delays and timeout duration definitions */
#define SATA_EVNT_DAEMON_SLEEP_TIME 50000 /* 50 ms */
#define SATA_EVNT_DAEMON_TERM_TIMEOUT 100000 /* 100 ms */
#define SATA_EVNT_DAEMON_TERM_WAIT 60000000 /* 60 s */
#define SATA_EVNT_LINK_LOST_TIMEOUT 1000000 /* 1 s */
#define SATA_DEV_IDENTIFY_TIMEOUT 60000000 /* 60 s, device enumeration */
#define SATA_DEV_REPROBE_TIMEOUT 30000000 /* 30 s, dev resp after rst */
#define SATA_DEV_RETRY_DLY 10000 /* 10 ms */
/* DEVICE IDENTIFY and device initialization retry delay */
#define SATA_DEV_IDENTIFY_RETRY 1
#define SATA_DEV_IDENTIFY_NORETRY 0
/*
* sata_scsi's hba_open_flag: field indicating open devctl instance.
* 0 = closed, 1 = shared open, 2 = exclusive open.
*/
#define SATA_DEVCTL_CLOSED 0
#define SATA_DEVCTL_SOPENED 1
#define SATA_DEVCTL_EXOPENED 2
/*
* sata_pkt_txlate structure contains info about resources allocated
* for the packet
* Address of this structure is stored in scsi_pkt.pkt_ha_private and
* in sata_pkt.sata_hba_private fields, so all three strucures are
* cross-linked, with sata_pkt_txlate as a centerpiece.
*/
typedef struct sata_pkt_txlate {
struct sata_hba_inst *txlt_sata_hba_inst;
struct scsi_pkt *txlt_scsi_pkt;
struct sata_pkt *txlt_sata_pkt;
ddi_dma_handle_t txlt_buf_dma_handle;
uint_t txlt_flags; /* data-in / data-out */
uint_t txlt_num_dma_win; /* number of DMA windows */
uint_t txlt_cur_dma_win; /* current DMA window */
/* cookies in the current DMA window */
uint_t txlt_curwin_num_dma_cookies;
/* processed dma cookies in current DMA win */
uint_t txlt_curwin_processed_dma_cookies;
size_t txlt_total_residue;
ddi_dma_cookie_t txlt_dma_cookie; /* default dma cookie */
int txlt_dma_cookie_list_len; /* alloc list len */
ddi_dma_cookie_t *txlt_dma_cookie_list; /* dma cookie list */
int txlt_num_dma_cookies; /* dma cookies in list */
/* temporary buffer access handle */
ddi_acc_handle_t txlt_tmp_buf_handle;
caddr_t txlt_tmp_buf; /* temp buffer address */
} sata_pkt_txlate_t;
_NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_pkt_txlate))
_NOTE(SCHEME_PROTECTS_DATA("unshared data", scsi_pkt))
/* Length of largest sense buffer used by sata */
#define SATA_MAX_SENSE_LEN MAX(sizeof (struct scsi_arq_status), \
sizeof (struct scsi_arq_status) - sizeof (struct scsi_extended_sense) + \
sizeof (struct scsi_descr_sense_hdr) + \
MAX(sizeof (struct scsi_cmd_specific_sense_descr), \
sizeof (struct scsi_ata_status_ret_sense_descr)))
/*
* Sense Data structure for ATA Pass Through
* This is the entire sense data block passed back up to scsi. It is
* effectively the scsi_arq_status structure for ATA Sense Return descriptor
* format sense data.
*/
struct sata_apt_sense_data {
struct scsi_status apt_status;
struct scsi_status apt_rqpkt_status;
uchar_t apt_rqpkt_reason;
uchar_t apt_rqpkt_resid;
uint_t apt_rqpkt_state;
uint_t apt_rqpkt_statistics;
struct scsi_descr_sense_hdr apt_sd_hdr;
struct scsi_ata_status_ret_sense_descr apt_sd_sense;
};
/*
* Additional scsi sense code definitions.
* These definition should eventually be moved to scsi header file
* usr/src/uts/common/sys/scsi/generic/sense.h
*/
#define SD_SCSI_ASC_NO_ADD_SENSE 0x00
#define SD_SCSI_ASC_APT_INFO_AVAIL 0x00
#define SD_SCSI_ASC_LU_NOT_READY 0x04
#define SD_SCSI_ASC_LU_NOT_RESPONSE 0x05
#define SD_SCSI_ASC_WRITE_ERR 0x0c
#define SD_SCSI_ASC_UNREC_READ_ERR 0x11
#define SD_SCSI_ASC_INVALID_COMMAND_CODE 0x20
#define SD_SCSI_ASC_LBA_OUT_OF_RANGE 0x21
#define SD_SCSI_ASC_INVALID_FIELD_IN_CDB 0x24
#define SD_SCSI_ASC_INVALID_FIELD_IN_PARAMS_LIST 0x26
#define SD_SCSI_ASC_WRITE_PROTECTED 0x27
#define SD_SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED 0x28
#define SD_SCSI_ASC_RESET 0x29
#define SD_SCSI_ASC_CMD_SEQUENCE_ERR 0x2c
#define SD_SCSI_ASC_MEDIUM_NOT_PRESENT 0x3a
#define SD_SCSI_ASC_SAVING_PARAMS_NOT_SUPPORTED 0x39
#define SD_SCSI_ASC_INTERNAL_TARGET_FAILURE 0x44
#define SD_SCSI_ASC_INFO_UNIT_IUCRC_ERR 0x47
#define SD_SCSI_ASC_OP_MEDIUM_REM_REQ 0x5a
#define SD_SCSI_ASC_LOW_POWER_CONDITION_ON 0x5e
/* SCSI defs missing from scsi headers */
/* Missing from sys/scsi/generic/commands.h */
#define SCMD_SYNCHRONIZE_CACHE_G1 0x91
/*
* Missing from sys/scsi/impl/mode.h, although defined
* in sys/scsi/targets/sddefs.h as MODEPAGE_ERR_RECOV
*/
#define MODEPAGE_RW_ERRRECOV 0x01 /* read/write recovery */
/* Missing from sys/scsi/impl/commands.h */
#define SCSI_READ_CAPACITY16_MAX_LBA 0xfffffffffffffffe
/*
* medium access command
*/
#define SATA_IS_MEDIUM_ACCESS_CMD(cmd) \
(((cmd) == SCMD_READ) || ((cmd) == SCMD_WRITE) || \
((cmd) == SCMD_READ_G1) || ((cmd) == SCMD_WRITE_G1) || \
((cmd) == SCMD_READ_G4) || ((cmd) == SCMD_WRITE_G4) || \
((cmd) == SCMD_READ_G5) || ((cmd) == SCMD_WRITE_G5) || \
((cmd) == SCMD_VERIFY) || ((cmd) == SCMD_VERIFY_G4) || \
((cmd) == SCMD_VERIFY_G5) || ((cmd) == 0x7f) /* VERIFY(32) */|| \
((cmd) == SCMD_SYNCHRONIZE_CACHE) || ((cmd) == SCMD_SPACE_G4) || \
((cmd) == SCMD_READ_POSITION) || \
((cmd) == 0x90) /* PRE-FETCH(16) */ || \
((cmd) == SCMD_READ_DEFECT_LIST) || \
((cmd) == 0xb7) /* READ DEFECT DATA */ || \
((cmd) == SCMD_READ_LONG) || ((cmd) == SCMD_SVC_ACTION_IN_G4) || \
((cmd) == SCMD_WRITE_LONG) || ((cmd) == SCMD_SVC_ACTION_OUT_G4) || \
((cmd) == 0x41) || ((cmd) == 0x93) || /* WRITE SAME */ \
((cmd) == 0x52) || ((cmd) == 0x50) || /* XDREAD & XDWRITE */ \
((cmd) == 0x53) || ((cmd) == 0x51) || /* XDWRITEREAD & XPWRITE */ \
((cmd) == 0x7f))
/*
* Macros for accessing various structure fields
*/
#define SATA_TRAN(sata_hba_inst) \
sata_hba_inst->satahba_tran
#define SATA_DIP(sata_hba_inst) \
sata_hba_inst->satahba_dip
#define SATA_NUM_CPORTS(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_hba_num_cports
#define SATA_QDEPTH(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_hba_qdepth
#define SATA_FEATURES(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_hba_features_support
#define SATA_DMA_ATTR(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_hba_dma_attr
#define SATA_START_FUNC(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_start
#define SATA_ABORT_FUNC(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_abort
#define SATA_RESET_DPORT_FUNC(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_reset_dport
#define SATA_PORT_DEACTIVATE_FUNC(sata_hba_inst) \
(sata_hba_inst->satahba_tran->sata_tran_hotplug_ops == NULL ? \
NULL : \
sata_hba_inst->satahba_tran->sata_tran_hotplug_ops->\
sata_tran_port_deactivate)
#define SATA_PORT_ACTIVATE_FUNC(sata_hba_inst) \
(sata_hba_inst->satahba_tran->sata_tran_hotplug_ops == NULL ? \
NULL : \
sata_hba_inst->satahba_tran->sata_tran_hotplug_ops->\
sata_tran_port_activate)
#define SATA_PROBE_PORT_FUNC(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_probe_port
#define SATA_SELFTEST_FUNC(sata_hba_inst) \
sata_hba_inst->satahba_tran->sata_tran_selftest
#define SATA_CPORT_MUTEX(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_mutex
#define SATA_CPORT_INFO(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]
#define SATA_CPORT_STATE(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_state
#define SATA_CPORT_EVENT_FLAGS(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_event_flags
#define SATA_CPORT_SCR(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_scr
#define SATA_CPORT_DEV_TYPE(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_dev_type
#define SATA_CPORT_DRV_INFO(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_devp.cport_sata_drive
#define SATA_CPORTINFO_DRV_TYPE(cportinfo) \
cportinfo->cport_dev_type
#define SATA_CPORTINFO_DRV_INFO(cportinfo) \
cportinfo->cport_devp.cport_sata_drive
#define SATA_CPORTINFO_PMULT_INFO(cportinfo) \
cportinfo->cport_devp.cport_sata_pmult
#define SATA_PMULT_INFO(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->cport_devp.cport_sata_pmult
#define SATA_NUM_PMPORTS(sata_hba_inst, cport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_num_dev_ports
#define SATA_PMPORT_MUTEX(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->pmport_mutex
#define SATA_PMPORT_INFO(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]
#define SATA_PMPORT_DRV_INFO(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->\
pmport_sata_drive
#define SATA_PMPORT_STATE(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->pmport_state
#define SATA_PMPORT_SCR(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->pmport_scr
#define SATA_PMPORT_DEV_TYPE(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->pmport_dev_type
#define SATA_PMPORT_EVENT_FLAGS(sata_hba_inst, cport, pmport) \
sata_hba_inst->satahba_dev_port[cport]->\
cport_devp.cport_sata_pmult->pmult_dev_port[pmport]->\
pmport_event_flags
#define SATA_PMPORTINFO_DRV_TYPE(pmportinfo) \
pmportinfo->pmport_dev_type
#define SATA_PMPORTINFO_DRV_INFO(pmportinfo) \
pmportinfo->pmport_sata_drive
#define SATA_TXLT_HBA_INST(spx) \
spx->txlt_sata_hba_inst
#define SATA_TXLT_CPORT(spx) \
spx->txlt_sata_pkt->satapkt_device.satadev_addr.cport
#define SATA_TXLT_PMPORT(spx) \
spx->txlt_sata_pkt->satapkt_device.satadev_addr.pmport
#define SATA_TXLT_QUAL(spx) \
spx->txlt_sata_pkt->satapkt_device.satadev_addr.qual
#define SATA_TXLT_CPORT_MUTEX(spx) \
spx->txlt_sata_hba_inst->\
satahba_dev_port[spx->txlt_sata_pkt->\
satapkt_device.satadev_addr.cport]->cport_mutex
#define SATA_TXLT_TASKQ(spx) \
spx->txlt_sata_hba_inst->\
satahba_taskq
/*
* Minor number construction for devctl and attachment point nodes.
* All necessary information has to be encoded in NBITSMINOR32 bits.
*
* Devctl node minor number:
* ((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | SATA_DEVCTL_NODE)
*
* Attachment point node minor number has to include controller
* instance (7 bits), controller port number (5 bits) and port multiplier
* device port number (4 bits) and port multiplier device port
* indicator (1 bit). Additionally, a single bit is used to
* differentiate between attachment point node and device control node.
*
* Attachment point minor number:
* ((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | SATA_AP_NODE |
* [(port_multiplier_device_port << SATA_PMULT_PORT_SHIFT) | SATA_PMULT_AP] |
* (controller_port))
*
* 17 bits are used (if 64 instances of controllers are expected)
* bit 18 is reserved for future use.
*
* --------------------------------------------------------
* |17|16|15|14|13|12|11|10 |09|08|07|06|05|04|03|02|01|00|
* --------------------------------------------------------
* | R| c| c| c| c| c| c|a/d|pm|pp|pp|pp|pp|cp|cp|cp|cp|cp|
* --------------------------------------------------------
* Where:
* cp - device port number on the HBA SATA controller
* pp - device port number on the port multiplier
* pm - 0 - target attached to controller device port
* 1 - target attached to port multiplier's device port
* a/d - 0 - devctl node
* 1 - attachment point node
* c - controller number
* R - reserved bit
*/
#define SATA_AP_NODE 0x400 /* Attachment Point node */
#define SATA_DEVCTL_NODE 0x000 /* DEVCTL node */
#define SATA_PMULT_AP 0x200 /* device on PMult port */
#define SATA_PMULT_PORT_SHIFT 5
#define SATA_CNTRL_INSTANCE_SHIFT 11
#define SATA_CPORT_MASK 0x1f /* 32 device ports */
#define SATA_PMULT_PORT_MASK 0xf /* 15 device ports */
#define SATA_CNTRL_INSTANCE_MASK 0x03F /* 64 controllers */
/* Macro for creating devctl node minor number */
#define SATA_MAKE_DEVCTL_MINOR(controller_instance) \
((controller_instance << SATA_CNTRL_INSTANCE_SHIFT) | \
SATA_DEVCTL_NODE)
/* Macro for creating an attachment point node minor number */
#define SATA_MAKE_AP_MINOR(cntrl_instance, cport, pmport, qual) \
(qual & (SATA_ADDR_PMPORT | SATA_ADDR_DPMPORT) ? \
(((cntrl_instance) << SATA_CNTRL_INSTANCE_SHIFT) | \
SATA_AP_NODE | SATA_PMULT_AP | \
(pmport << SATA_PMULT_PORT_SHIFT) | cport) : \
(((cntrl_instance) << SATA_CNTRL_INSTANCE_SHIFT) | \
SATA_AP_NODE | cport))
/* Macro retrieving controller number from a minor number */
#define SATA_MINOR2INSTANCE(minor) \
((minor >> SATA_CNTRL_INSTANCE_SHIFT) & SATA_CNTRL_INSTANCE_MASK)
/*
* Macro for creating an attachment point number from sata address.
* Address qualifier has to be one of:
* SATA_ADDR_DCPORT, SATA_ADDR_DPMPORT, SATA_ADDR_CPORT or SATA_ADDR_PMPORT
*/
#define SATA_MAKE_AP_NUMBER(cport, pmport, qual) \
((qual & (SATA_ADDR_PMPORT | SATA_ADDR_DPMPORT)) ? \
(SATA_PMULT_AP | (pmport << SATA_PMULT_PORT_SHIFT) | cport) : \
(cport))
/*
* SCSI target number format
*
* -------------------------------
* | 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| Bit number
* -------------------------------
* |pm|pp|pp|pp|pp|cp|cp|cp|cp|cp|
* -------------------------------
* Where:
* cp - device port number on the HBA SATA controller
* pp - device port number on the port multiplier
* pm - 0 - target attached to controller device port
* 1 - target attached to port multiplier's device port
*/
/* SATA ports to SCSI target number translation */
#define SATA_TO_SCSI_TARGET(cport, pmport, qual) \
(qual == SATA_ADDR_DCPORT ? cport : \
(cport | (pmport << SATA_PMULT_PORT_SHIFT) | SATA_PMULT_AP))
/* SCSI target number to SATA cntrl/pmport/cport translations */
#define SCSI_TO_SATA_CPORT(scsi_target) \
(scsi_target & SATA_CPORT_MASK)
#define SCSI_TO_SATA_PMPORT(scsi_target) \
((scsi_target >> SATA_PMULT_PORT_SHIFT) & SATA_PMULT_PORT_MASK)
#define SCSI_TO_SATA_ADDR_QUAL(scsi_target) \
((scsi_target & SATA_PMULT_AP) ? SATA_ADDR_DPMPORT : \
SATA_ADDR_DCPORT)
/* Debug flags */
#if DEBUG
#define SATA_DEBUG
#define SATA_DBG_SCSI_IF 1
#define SATA_DBG_HBA_IF 2
#define SATA_DBG_NODES 4
#define SATA_DBG_IOCTL_IF 8
#define SATA_DBG_EVENTS 0x10
#define SATA_DBG_EVENTS_PROC 0x20
#define SATA_DBG_EVENTS_PROCPST 0x40
#define SATA_DBG_EVENTS_CNTRL 0x80
#define SATA_DBG_EVENTS_DAEMON 0x100
#define SATA_DBG_DMA_SETUP 0x400
#define SATA_DBG_DEV_SETTINGS 0x800
#define SATA_DBG_ATAPI 0x1000
#define SATA_DBG_ATAPI_PACKET 0x8000
#define SATA_DBG_INTR_CTX 0x10000
#define SATA_DBG_PMULT 0x20000
typedef struct sata_atapi_cmd {
uint8_t acdb[SATA_ATAPI_MAX_CDB_LEN];
uint8_t arqs[SATA_ATAPI_RQSENSE_LEN];
uint_t sata_pkt_reason;
uint_t scsi_pkt_reason;
} sata_atapi_cmd_t;
/* Debug macros */
#define SATADBG1(flag, sata, format, arg1) \
if (sata_debug_flags & (flag)) { \
sata_log(sata, CE_CONT, format, arg1); \
}
#define SATADBG2(flag, sata, format, arg1, arg2) \
if (sata_debug_flags & (flag)) { \
sata_log(sata, CE_CONT, format, arg1, arg2); \
}
#define SATADBG3(flag, sata, format, arg1, arg2, arg3) \
if (sata_debug_flags & (flag)) { \
sata_log(sata, CE_CONT, format, arg1, arg2, arg3); \
}
#else
#define SATADBG1(flag, dip, frmt, arg1)
#define SATADBG2(flag, dip, frmt, arg1, arg2)
#define SATADBG3(flag, dip, frmt, arg1, arg2, arg3)
#endif
/* sata_rev_tag 1.46 */
#ifdef __cplusplus
}
#endif
#endif /* _SATA_H */
|