satafis_subr.c revision 1.7 1 1.7 jakllsch /* $NetBSD: satafis_subr.c,v 1.7 2012/07/22 17:57:57 jakllsch Exp $ */
2 1.1 jakllsch
3 1.1 jakllsch /*-
4 1.1 jakllsch * Copyright (c) 2009 Jonathan A. Kollasch.
5 1.1 jakllsch * All rights reserved.
6 1.1 jakllsch *
7 1.1 jakllsch * Redistribution and use in source and binary forms, with or without
8 1.1 jakllsch * modification, are permitted provided that the following conditions
9 1.1 jakllsch * are met:
10 1.1 jakllsch * 1. Redistributions of source code must retain the above copyright
11 1.1 jakllsch * notice, this list of conditions and the following disclaimer.
12 1.1 jakllsch * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 jakllsch * notice, this list of conditions and the following disclaimer in the
14 1.1 jakllsch * documentation and/or other materials provided with the distribution.
15 1.1 jakllsch *
16 1.1 jakllsch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 jakllsch * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 jakllsch * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 jakllsch * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 jakllsch * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.1 jakllsch * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.1 jakllsch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.1 jakllsch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.1 jakllsch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.1 jakllsch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.1 jakllsch */
27 1.1 jakllsch
28 1.1 jakllsch /*
29 1.1 jakllsch * Copyright (c) 2006 Manuel Bouyer.
30 1.1 jakllsch *
31 1.1 jakllsch * Redistribution and use in source and binary forms, with or without
32 1.1 jakllsch * modification, are permitted provided that the following conditions
33 1.1 jakllsch * are met:
34 1.1 jakllsch * 1. Redistributions of source code must retain the above copyright
35 1.1 jakllsch * notice, this list of conditions and the following disclaimer.
36 1.1 jakllsch * 2. Redistributions in binary form must reproduce the above copyright
37 1.1 jakllsch * notice, this list of conditions and the following disclaimer in the
38 1.1 jakllsch * documentation and/or other materials provided with the distribution.
39 1.1 jakllsch *
40 1.1 jakllsch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
41 1.1 jakllsch * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42 1.1 jakllsch * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
43 1.1 jakllsch * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
44 1.1 jakllsch * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 1.1 jakllsch * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
46 1.1 jakllsch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
47 1.1 jakllsch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
48 1.1 jakllsch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
49 1.1 jakllsch * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 1.1 jakllsch *
51 1.1 jakllsch */
52 1.1 jakllsch
53 1.1 jakllsch #include <sys/cdefs.h>
54 1.7 jakllsch __KERNEL_RCSID(0, "$NetBSD: satafis_subr.c,v 1.7 2012/07/22 17:57:57 jakllsch Exp $");
55 1.1 jakllsch
56 1.1 jakllsch #include <sys/param.h>
57 1.2 jakllsch #include <sys/systm.h>
58 1.1 jakllsch
59 1.1 jakllsch #include <sys/disklabel.h>
60 1.1 jakllsch
61 1.1 jakllsch #include <dev/ata/atareg.h>
62 1.1 jakllsch #include <dev/ata/atavar.h>
63 1.1 jakllsch
64 1.1 jakllsch #include <dev/ata/satafisreg.h>
65 1.1 jakllsch #include <dev/ata/satafisvar.h>
66 1.1 jakllsch
67 1.1 jakllsch #include "atapibus.h"
68 1.1 jakllsch
69 1.1 jakllsch void
70 1.1 jakllsch satafis_rhd_construct_cmd(struct ata_command *ata_c, uint8_t *fis)
71 1.1 jakllsch {
72 1.6 jakllsch
73 1.2 jakllsch memset(fis, 0, RHD_FISLEN);
74 1.2 jakllsch
75 1.1 jakllsch fis[fis_type] = RHD_FISTYPE;
76 1.5 jakllsch fis[rhd_c] = RHD_C;
77 1.1 jakllsch fis[rhd_command] = ata_c->r_command;
78 1.6 jakllsch fis[rhd_features0] = (ata_c->r_features >> 0) & 0xff;
79 1.6 jakllsch
80 1.6 jakllsch fis[rhd_lba0] = (ata_c->r_lba >> 0) & 0xff;
81 1.6 jakllsch fis[rhd_lba1] = (ata_c->r_lba >> 8) & 0xff;
82 1.6 jakllsch fis[rhd_lba2] = (ata_c->r_lba >> 16) & 0xff;
83 1.6 jakllsch if ((ata_c->flags & AT_LBA48) != 0) {
84 1.7 jakllsch fis[rhd_dh] = ata_c->r_device;
85 1.6 jakllsch fis[rhd_lba3] = (ata_c->r_lba >> 24) & 0xff;
86 1.6 jakllsch fis[rhd_lba4] = (ata_c->r_lba >> 32) & 0xff;
87 1.6 jakllsch fis[rhd_lba5] = (ata_c->r_lba >> 40) & 0xff;
88 1.6 jakllsch fis[rhd_features1] = (ata_c->r_features >> 8) & 0xff;
89 1.6 jakllsch } else {
90 1.7 jakllsch fis[rhd_dh] = (ata_c->r_device & 0xf0) |
91 1.7 jakllsch ((ata_c->r_lba >> 24) & 0x0f);
92 1.6 jakllsch }
93 1.6 jakllsch
94 1.6 jakllsch fis[rhd_count0] = (ata_c->r_count >> 0) & 0xff;
95 1.6 jakllsch if ((ata_c->flags & AT_LBA48) != 0) {
96 1.6 jakllsch fis[rhd_count1] = (ata_c->r_count >> 8) & 0xff;
97 1.6 jakllsch }
98 1.1 jakllsch }
99 1.1 jakllsch
100 1.1 jakllsch void
101 1.1 jakllsch satafis_rhd_construct_bio(struct ata_xfer *xfer, uint8_t *fis)
102 1.1 jakllsch {
103 1.1 jakllsch struct ata_bio *ata_bio = xfer->c_cmd;
104 1.1 jakllsch int nblks;
105 1.1 jakllsch
106 1.1 jakllsch nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
107 1.1 jakllsch
108 1.2 jakllsch memset(fis, 0, RHD_FISLEN);
109 1.2 jakllsch
110 1.1 jakllsch fis[fis_type] = RHD_FISTYPE;
111 1.5 jakllsch fis[rhd_c] = RHD_C;
112 1.1 jakllsch if (ata_bio->flags & ATA_LBA48) {
113 1.1 jakllsch fis[rhd_command] = (ata_bio->flags & ATA_READ) ?
114 1.1 jakllsch WDCC_READDMA_EXT : WDCC_WRITEDMA_EXT;
115 1.1 jakllsch } else {
116 1.1 jakllsch fis[rhd_command] =
117 1.1 jakllsch (ata_bio->flags & ATA_READ) ? WDCC_READDMA : WDCC_WRITEDMA;
118 1.1 jakllsch }
119 1.6 jakllsch
120 1.6 jakllsch fis[rhd_lba0] = (ata_bio->blkno >> 0) & 0xff;
121 1.6 jakllsch fis[rhd_lba1] = (ata_bio->blkno >> 8) & 0xff;
122 1.6 jakllsch fis[rhd_lba2] = (ata_bio->blkno >> 16) & 0xff;
123 1.6 jakllsch if ((ata_bio->flags & ATA_LBA48) != 0) {
124 1.1 jakllsch fis[rhd_dh] = WDSD_LBA;
125 1.6 jakllsch fis[rhd_lba3] = (ata_bio->blkno >> 24) & 0xff;
126 1.6 jakllsch fis[rhd_lba4] = (ata_bio->blkno >> 32) & 0xff;
127 1.6 jakllsch fis[rhd_lba5] = (ata_bio->blkno >> 40) & 0xff;
128 1.1 jakllsch } else {
129 1.6 jakllsch fis[rhd_dh] = ((ata_bio->blkno >> 24) & 0x0f) |
130 1.6 jakllsch (((ata_bio->flags & ATA_LBA) != 0) ? WDSD_LBA : 0);
131 1.6 jakllsch }
132 1.6 jakllsch
133 1.6 jakllsch fis[rhd_count0] = nblks & 0xff;
134 1.6 jakllsch if ((ata_bio->flags & ATA_LBA48) != 0) {
135 1.6 jakllsch fis[rhd_count1] = (nblks >> 8) & 0xff;
136 1.1 jakllsch }
137 1.1 jakllsch }
138 1.1 jakllsch
139 1.1 jakllsch #if NATAPIBUS > 0
140 1.1 jakllsch void
141 1.1 jakllsch satafis_rhd_construct_atapi(struct ata_xfer *xfer, uint8_t *fis)
142 1.1 jakllsch {
143 1.6 jakllsch
144 1.2 jakllsch memset(fis, 0, RHD_FISLEN);
145 1.2 jakllsch
146 1.1 jakllsch fis[fis_type] = RHD_FISTYPE;
147 1.5 jakllsch fis[rhd_c] = RHD_C;
148 1.1 jakllsch fis[rhd_command] = ATAPI_PKT_CMD;
149 1.6 jakllsch fis[rhd_features0] = (xfer->c_flags & C_DMA) ?
150 1.1 jakllsch ATAPI_PKT_CMD_FTRE_DMA : 0;
151 1.1 jakllsch }
152 1.1 jakllsch #endif /* NATAPIBUS */
153 1.1 jakllsch
154 1.1 jakllsch void
155 1.5 jakllsch satafis_rdh_parse(struct ata_channel *chp, const uint8_t *fis)
156 1.1 jakllsch {
157 1.6 jakllsch
158 1.3 jakllsch chp->ch_status = fis[rdh_status];
159 1.3 jakllsch chp->ch_error = fis[rdh_error];
160 1.5 jakllsch }
161 1.1 jakllsch
162 1.5 jakllsch void
163 1.5 jakllsch satafis_rdh_cmd_readreg(struct ata_command *ata_c, const uint8_t *fis)
164 1.5 jakllsch {
165 1.6 jakllsch
166 1.6 jakllsch ata_c->r_lba = (uint64_t)fis[rdh_lba0] << 0;
167 1.6 jakllsch ata_c->r_lba |= (uint64_t)fis[rdh_lba1] << 8;
168 1.6 jakllsch ata_c->r_lba |= (uint64_t)fis[rdh_lba2] << 16;
169 1.6 jakllsch if ((ata_c->flags & AT_LBA48) != 0) {
170 1.6 jakllsch ata_c->r_lba |= (uint64_t)fis[rdh_lba3] << 24;
171 1.6 jakllsch ata_c->r_lba |= (uint64_t)fis[rdh_lba4] << 32;
172 1.6 jakllsch ata_c->r_lba |= (uint64_t)fis[rdh_lba5] << 40;
173 1.7 jakllsch ata_c->r_device = fis[rdh_dh];
174 1.6 jakllsch } else {
175 1.6 jakllsch ata_c->r_lba |= (uint64_t)(fis[rdh_dh] & 0x0f) << 24;
176 1.7 jakllsch ata_c->r_device = fis[rdh_dh] & 0xf0;
177 1.6 jakllsch }
178 1.6 jakllsch
179 1.6 jakllsch ata_c->r_count = fis[rdh_count0] << 0;
180 1.6 jakllsch if ((ata_c->flags & AT_LBA48) != 0) {
181 1.6 jakllsch ata_c->r_count |= fis[rdh_count1] << 8;
182 1.6 jakllsch }
183 1.6 jakllsch
184 1.5 jakllsch ata_c->r_error = fis[rdh_error];
185 1.6 jakllsch ata_c->r_status = fis[rdh_status];
186 1.1 jakllsch }
187