2 * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification, immediately at the beginning of the file.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/libkern.h>
37 #include <sys/kernel.h>
38 #include <sys/sysctl.h>
45 #define min(a,b) (((a)<(b))?(a):(b))
50 #include <cam/cam_ccb.h>
51 #include <cam/cam_queue.h>
52 #include <cam/cam_xpt.h>
54 #include <cam/ata/ata_all.h>
56 #include <sys/endian.h>
65 for (bit = 15; bit >= 0; bit--)
72 ata_print_ident(struct ata_params *ident_data)
74 char product[48], revision[16];
76 cam_strvis(product, ident_data->model, sizeof(ident_data->model),
78 cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
80 printf("<%s %s> ATA/ATAPI-%d",
81 product, revision, ata_version(ident_data->version_major));
82 if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
83 if (ident_data->satacapabilities & ATA_SATA_GEN2)
85 else if (ident_data->satacapabilities & ATA_SATA_GEN1)
94 ata_36bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
95 uint32_t lba, uint8_t sector_count)
97 bzero(&ataio->cmd, sizeof(ataio->cmd));
99 ataio->cmd.command = cmd;
100 ataio->cmd.features = features;
101 ataio->cmd.lba_low = lba;
102 ataio->cmd.lba_mid = lba >> 8;
103 ataio->cmd.lba_high = lba >> 16;
104 ataio->cmd.device = 0x40 | ((lba >> 24) & 0x0f);
105 ataio->cmd.sector_count = sector_count;
109 ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
110 uint64_t lba, uint16_t sector_count)
112 bzero(&ataio->cmd, sizeof(ataio->cmd));
113 ataio->cmd.flags = CAM_ATAIO_48BIT;
114 ataio->cmd.command = cmd;
115 ataio->cmd.features = features;
116 ataio->cmd.lba_low = lba;
117 ataio->cmd.lba_mid = lba >> 8;
118 ataio->cmd.lba_high = lba >> 16;
119 ataio->cmd.device = 0x40;
120 ataio->cmd.lba_low_exp = lba >> 24;
121 ataio->cmd.lba_mid_exp = lba >> 32;
122 ataio->cmd.lba_high_exp = lba >> 40;
123 ataio->cmd.features_exp = features >> 8;
124 ataio->cmd.sector_count = sector_count;
125 ataio->cmd.sector_count_exp = sector_count >> 8;
129 ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
130 uint64_t lba, uint16_t sector_count)
132 bzero(&ataio->cmd, sizeof(ataio->cmd));
133 ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_FPDMA;
134 ataio->cmd.command = cmd;
135 ataio->cmd.features = sector_count;
136 ataio->cmd.lba_low = lba;
137 ataio->cmd.lba_mid = lba >> 8;
138 ataio->cmd.lba_high = lba >> 16;
139 ataio->cmd.device = 0x40;
140 ataio->cmd.lba_low_exp = lba >> 24;
141 ataio->cmd.lba_mid_exp = lba >> 32;
142 ataio->cmd.lba_high_exp = lba >> 40;
143 ataio->cmd.features_exp = sector_count >> 8;
147 ata_reset_cmd(struct ccb_ataio *ataio)
149 bzero(&ataio->cmd, sizeof(ataio->cmd));
150 ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT;
151 ataio->cmd.control = 0x04;
155 ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port)
157 bzero(&ataio->cmd, sizeof(ataio->cmd));
158 ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT;
159 ataio->cmd.command = ATA_READ_PM;
160 ataio->cmd.features = reg;
161 ataio->cmd.features_exp = reg >> 8;
162 ataio->cmd.device = port & 0x0f;
166 ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint64_t val)
168 bzero(&ataio->cmd, sizeof(ataio->cmd));
169 ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_NEEDRESULT;
170 ataio->cmd.command = ATA_WRITE_PM;
171 ataio->cmd.features = reg;
172 ataio->cmd.lba_low = val >> 8;
173 ataio->cmd.lba_mid = val >> 16;
174 ataio->cmd.lba_high = val >> 24;
175 ataio->cmd.device = port & 0x0f;
176 ataio->cmd.lba_low_exp = val >> 40;
177 ataio->cmd.lba_mid_exp = val >> 48;
178 ataio->cmd.lba_high_exp = val >> 56;
179 ataio->cmd.features_exp = reg >> 8;
180 ataio->cmd.sector_count = val;
181 ataio->cmd.sector_count_exp = val >> 32;
185 ata_bswap(int8_t *buf, int len)
187 u_int16_t *ptr = (u_int16_t*)(buf + len);
189 while (--ptr >= (u_int16_t*)buf)
190 *ptr = be16toh(*ptr);
194 ata_btrim(int8_t *buf, int len)
198 for (ptr = buf; ptr < buf+len; ++ptr)
199 if (!*ptr || *ptr == '_')
201 for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
206 ata_bpack(int8_t *src, int8_t *dst, int len)
210 for (i = j = blank = 0 ; i < len; i++) {
211 if (blank && src[i] == ' ') continue;
212 if (blank && src[i] != ' ') {
229 ata_max_pmode(struct ata_params *ap)
231 if (ap->atavalid & ATA_FLAG_64_70) {
232 if (ap->apiomodes & 0x02)
234 if (ap->apiomodes & 0x01)
237 if (ap->mwdmamodes & 0x04)
239 if (ap->mwdmamodes & 0x02)
241 if (ap->mwdmamodes & 0x01)
243 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
245 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
247 if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000)
253 ata_max_wmode(struct ata_params *ap)
255 if (ap->mwdmamodes & 0x04)
257 if (ap->mwdmamodes & 0x02)
259 if (ap->mwdmamodes & 0x01)
265 ata_max_umode(struct ata_params *ap)
267 if (ap->atavalid & ATA_FLAG_88) {
268 if (ap->udmamodes & 0x40)
270 if (ap->udmamodes & 0x20)
272 if (ap->udmamodes & 0x10)
274 if (ap->udmamodes & 0x08)
276 if (ap->udmamodes & 0x04)
278 if (ap->udmamodes & 0x02)
280 if (ap->udmamodes & 0x01)
287 ata_max_mode(struct ata_params *ap, int mode, int maxmode)
290 if (maxmode && mode > maxmode)
293 if (mode >= ATA_UDMA0 && ata_max_umode(ap) > 0)
294 return (min(mode, ata_max_umode(ap)));
296 if (mode >= ATA_WDMA0 && ata_max_wmode(ap) > 0)
297 return (min(mode, ata_max_wmode(ap)));
299 if (mode > ata_max_pmode(ap))
300 return (min(mode, ata_max_pmode(ap)));