xref: /freebsd/sys/cam/ata/ata_all.c (revision 8ef24a0d4b28fe230e20637f56869cc4148cd2ca)
1 /*-
2  * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
14  *
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.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 
32 #ifdef _KERNEL
33 #include <opt_scsi.h>
34 
35 #include <sys/systm.h>
36 #include <sys/libkern.h>
37 #include <sys/kernel.h>
38 #include <sys/sysctl.h>
39 #else
40 #include <errno.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #ifndef min
45 #define min(a,b) (((a)<(b))?(a):(b))
46 #endif
47 #endif
48 
49 #include <cam/cam.h>
50 #include <cam/cam_ccb.h>
51 #include <cam/cam_queue.h>
52 #include <cam/cam_xpt.h>
53 #include <sys/ata.h>
54 #include <cam/ata/ata_all.h>
55 #include <sys/sbuf.h>
56 #include <sys/endian.h>
57 
58 int
59 ata_version(int ver)
60 {
61 	int bit;
62 
63 	if (ver == 0xffff)
64 		return 0;
65 	for (bit = 15; bit >= 0; bit--)
66 		if (ver & (1<<bit))
67 			return bit;
68 	return 0;
69 }
70 
71 char *
72 ata_op_string(struct ata_cmd *cmd)
73 {
74 
75 	if (cmd->control & 0x04)
76 		return ("SOFT_RESET");
77 	switch (cmd->command) {
78 	case 0x00:
79 		switch (cmd->features) {
80 		case 0x00: return ("NOP FLUSHQUEUE");
81 		case 0x01: return ("NOP AUTOPOLL");
82 		}
83 		return ("NOP");
84 	case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR");
85 	case 0x06:
86 		switch (cmd->features) {
87 		case 0x01: return ("DSM TRIM");
88 		}
89 		return "DSM";
90 	case 0x08: return ("DEVICE_RESET");
91 	case 0x20: return ("READ");
92 	case 0x24: return ("READ48");
93 	case 0x25: return ("READ_DMA48");
94 	case 0x26: return ("READ_DMA_QUEUED48");
95 	case 0x27: return ("READ_NATIVE_MAX_ADDRESS48");
96 	case 0x29: return ("READ_MUL48");
97 	case 0x2a: return ("READ_STREAM_DMA48");
98 	case 0x2b: return ("READ_STREAM48");
99 	case 0x2f: return ("READ_LOG_EXT");
100 	case 0x30: return ("WRITE");
101 	case 0x34: return ("WRITE48");
102 	case 0x35: return ("WRITE_DMA48");
103 	case 0x36: return ("WRITE_DMA_QUEUED48");
104 	case 0x37: return ("SET_MAX_ADDRESS48");
105 	case 0x39: return ("WRITE_MUL48");
106 	case 0x3a: return ("WRITE_STREAM_DMA48");
107 	case 0x3b: return ("WRITE_STREAM48");
108 	case 0x3d: return ("WRITE_DMA_FUA48");
109 	case 0x3e: return ("WRITE_DMA_QUEUED_FUA48");
110 	case 0x3f: return ("WRITE_LOG_EXT");
111 	case 0x40: return ("READ_VERIFY");
112 	case 0x42: return ("READ_VERIFY48");
113 	case 0x45:
114 		switch (cmd->features) {
115 		case 0x55: return ("WRITE_UNCORRECTABLE48 PSEUDO");
116 		case 0xaa: return ("WRITE_UNCORRECTABLE48 FLAGGED");
117 		}
118 		return "WRITE_UNCORRECTABLE48";
119 	case 0x51: return ("CONFIGURE_STREAM");
120 	case 0x60: return ("READ_FPDMA_QUEUED");
121 	case 0x61: return ("WRITE_FPDMA_QUEUED");
122 	case 0x63: return ("NCQ_NON_DATA");
123 	case 0x64: return ("SEND_FPDMA_QUEUED");
124 	case 0x65: return ("RECEIVE_FPDMA_QUEUED");
125 	case 0x67:
126 		if (cmd->features == 0xec)
127 			return ("SEP_ATTN IDENTIFY");
128 		switch (cmd->lba_low) {
129 		case 0x00: return ("SEP_ATTN READ BUFFER");
130 		case 0x02: return ("SEP_ATTN RECEIVE DIAGNOSTIC RESULTS");
131 		case 0x80: return ("SEP_ATTN WRITE BUFFER");
132 		case 0x82: return ("SEP_ATTN SEND DIAGNOSTIC");
133 		}
134 		return ("SEP_ATTN");
135 	case 0x70: return ("SEEK");
136 	case 0x87: return ("CFA_TRANSLATE_SECTOR");
137 	case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
138 	case 0x92: return ("DOWNLOAD_MICROCODE");
139 	case 0xa0: return ("PACKET");
140 	case 0xa1: return ("ATAPI_IDENTIFY");
141 	case 0xa2: return ("SERVICE");
142 	case 0xb0:
143 		switch(cmd->features) {
144 		case 0xd0: return ("SMART READ ATTR VALUES");
145 		case 0xd1: return ("SMART READ ATTR THRESHOLDS");
146 		case 0xd3: return ("SMART SAVE ATTR VALUES");
147 		case 0xd4: return ("SMART EXECUTE OFFLINE IMMEDIATE");
148 		case 0xd5: return ("SMART READ LOG DATA");
149 		case 0xd8: return ("SMART ENABLE OPERATION");
150 		case 0xd9: return ("SMART DISABLE OPERATION");
151 		case 0xda: return ("SMART RETURN STATUS");
152 		}
153 		return ("SMART");
154 	case 0xb1: return ("DEVICE CONFIGURATION");
155 	case 0xc0: return ("CFA_ERASE");
156 	case 0xc4: return ("READ_MUL");
157 	case 0xc5: return ("WRITE_MUL");
158 	case 0xc6: return ("SET_MULTI");
159 	case 0xc7: return ("READ_DMA_QUEUED");
160 	case 0xc8: return ("READ_DMA");
161 	case 0xca: return ("WRITE_DMA");
162 	case 0xcc: return ("WRITE_DMA_QUEUED");
163 	case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE");
164 	case 0xce: return ("WRITE_MUL_FUA48");
165 	case 0xd1: return ("CHECK_MEDIA_CARD_TYPE");
166 	case 0xda: return ("GET_MEDIA_STATUS");
167 	case 0xde: return ("MEDIA_LOCK");
168 	case 0xdf: return ("MEDIA_UNLOCK");
169 	case 0xe0: return ("STANDBY_IMMEDIATE");
170 	case 0xe1: return ("IDLE_IMMEDIATE");
171 	case 0xe2: return ("STANDBY");
172 	case 0xe3: return ("IDLE");
173 	case 0xe4: return ("READ_BUFFER/PM");
174 	case 0xe5: return ("CHECK_POWER_MODE");
175 	case 0xe6: return ("SLEEP");
176 	case 0xe7: return ("FLUSHCACHE");
177 	case 0xe8: return ("WRITE_PM");
178 	case 0xea: return ("FLUSHCACHE48");
179 	case 0xec: return ("ATA_IDENTIFY");
180 	case 0xed: return ("MEDIA_EJECT");
181 	case 0xef:
182 		switch (cmd->features) {
183 		case 0x03: return ("SETFEATURES SET TRANSFER MODE");
184 		case 0x02: return ("SETFEATURES ENABLE WCACHE");
185 		case 0x82: return ("SETFEATURES DISABLE WCACHE");
186 		case 0x06: return ("SETFEATURES ENABLE PUIS");
187 		case 0x86: return ("SETFEATURES DISABLE PUIS");
188 		case 0x07: return ("SETFEATURES SPIN-UP");
189 		case 0x10: return ("SETFEATURES ENABLE SATA FEATURE");
190 		case 0x90: return ("SETFEATURES DISABLE SATA FEATURE");
191 		case 0xaa: return ("SETFEATURES ENABLE RCACHE");
192 		case 0x55: return ("SETFEATURES DISABLE RCACHE");
193 		case 0x5d: return ("SETFEATURES ENABLE RELIRQ");
194 		case 0xdd: return ("SETFEATURES DISABLE RELIRQ");
195 		case 0x5e: return ("SETFEATURES ENABLE SRVIRQ");
196 		case 0xde: return ("SETFEATURES DISABLE SRVIRQ");
197 		}
198 		return "SETFEATURES";
199 	case 0xf1: return ("SECURITY_SET_PASSWORD");
200 	case 0xf2: return ("SECURITY_UNLOCK");
201 	case 0xf3: return ("SECURITY_ERASE_PREPARE");
202 	case 0xf4: return ("SECURITY_ERASE_UNIT");
203 	case 0xf5: return ("SECURITY_FREEZE_LOCK");
204 	case 0xf6: return ("SECURITY_DISABLE_PASSWORD");
205 	case 0xf8: return ("READ_NATIVE_MAX_ADDRESS");
206 	case 0xf9: return ("SET_MAX_ADDRESS");
207 	}
208 	return "UNKNOWN";
209 }
210 
211 char *
212 ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len)
213 {
214 	struct sbuf sb;
215 	int error;
216 
217 	if (len == 0)
218 		return ("");
219 
220 	sbuf_new(&sb, cmd_string, len, SBUF_FIXEDLEN);
221 	ata_cmd_sbuf(cmd, &sb);
222 
223 	error = sbuf_finish(&sb);
224 	if (error != 0 && error != ENOMEM)
225 		return ("");
226 
227 	return(sbuf_data(&sb));
228 }
229 
230 void
231 ata_cmd_sbuf(struct ata_cmd *cmd, struct sbuf *sb)
232 {
233 	sbuf_printf(sb, "%02x %02x %02x %02x "
234 	    "%02x %02x %02x %02x %02x %02x %02x %02x",
235 	    cmd->command, cmd->features,
236 	    cmd->lba_low, cmd->lba_mid, cmd->lba_high, cmd->device,
237 	    cmd->lba_low_exp, cmd->lba_mid_exp, cmd->lba_high_exp,
238 	    cmd->features_exp, cmd->sector_count, cmd->sector_count_exp);
239 }
240 
241 char *
242 ata_res_string(struct ata_res *res, char *res_string, size_t len)
243 {
244 	struct sbuf sb;
245 	int error;
246 
247 	if (len == 0)
248 		return ("");
249 
250 	sbuf_new(&sb, res_string, len, SBUF_FIXEDLEN);
251 	ata_res_sbuf(res, &sb);
252 
253 	error = sbuf_finish(&sb);
254 	if (error != 0 && error != ENOMEM)
255 		return ("");
256 
257 	return(sbuf_data(&sb));
258 }
259 
260 int
261 ata_res_sbuf(struct ata_res *res, struct sbuf *sb)
262 {
263 
264 	sbuf_printf(sb, "%02x %02x %02x %02x "
265 	    "%02x %02x %02x %02x %02x %02x %02x",
266 	    res->status, res->error,
267 	    res->lba_low, res->lba_mid, res->lba_high, res->device,
268 	    res->lba_low_exp, res->lba_mid_exp, res->lba_high_exp,
269 	    res->sector_count, res->sector_count_exp);
270 
271 	return (0);
272 }
273 
274 /*
275  * ata_command_sbuf() returns 0 for success and -1 for failure.
276  */
277 int
278 ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb)
279 {
280 
281 	sbuf_printf(sb, "%s. ACB: ",
282 	    ata_op_string(&ataio->cmd));
283 	ata_cmd_sbuf(&ataio->cmd, sb);
284 
285 	return(0);
286 }
287 
288 /*
289  * ata_status_abuf() returns 0 for success and -1 for failure.
290  */
291 int
292 ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb)
293 {
294 
295 	sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s)",
296 	    ataio->res.status,
297 	    (ataio->res.status & 0x80) ? "BSY " : "",
298 	    (ataio->res.status & 0x40) ? "DRDY " : "",
299 	    (ataio->res.status & 0x20) ? "DF " : "",
300 	    (ataio->res.status & 0x10) ? "SERV " : "",
301 	    (ataio->res.status & 0x08) ? "DRQ " : "",
302 	    (ataio->res.status & 0x04) ? "CORR " : "",
303 	    (ataio->res.status & 0x02) ? "IDX " : "",
304 	    (ataio->res.status & 0x01) ? "ERR" : "");
305 	if (ataio->res.status & 1) {
306 	    sbuf_printf(sb, ", error: %02x (%s%s%s%s%s%s%s%s)",
307 		ataio->res.error,
308 		(ataio->res.error & 0x80) ? "ICRC " : "",
309 		(ataio->res.error & 0x40) ? "UNC " : "",
310 		(ataio->res.error & 0x20) ? "MC " : "",
311 		(ataio->res.error & 0x10) ? "IDNF " : "",
312 		(ataio->res.error & 0x08) ? "MCR " : "",
313 		(ataio->res.error & 0x04) ? "ABRT " : "",
314 		(ataio->res.error & 0x02) ? "NM " : "",
315 		(ataio->res.error & 0x01) ? "ILI" : "");
316 	}
317 
318 	return(0);
319 }
320 
321 void
322 ata_print_ident(struct ata_params *ident_data)
323 {
324 	const char *proto;
325 	char product[48], revision[16], ata[12], sata[12];
326 
327 	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
328 		   sizeof(product));
329 	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
330 		   sizeof(revision));
331 	proto = (ident_data->config == ATA_PROTO_CFA) ? "CFA" :
332 		(ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA";
333 	if (ata_version(ident_data->version_major) == 0) {
334 		snprintf(ata, sizeof(ata), "%s", proto);
335 	} else if (ata_version(ident_data->version_major) <= 7) {
336 		snprintf(ata, sizeof(ata), "%s-%d", proto,
337 		    ata_version(ident_data->version_major));
338 	} else if (ata_version(ident_data->version_major) == 8) {
339 		snprintf(ata, sizeof(ata), "%s8-ACS", proto);
340 	} else {
341 		snprintf(ata, sizeof(ata), "ACS-%d %s",
342 		    ata_version(ident_data->version_major) - 7, proto);
343 	}
344 	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
345 		if (ident_data->satacapabilities & ATA_SATA_GEN3)
346 			snprintf(sata, sizeof(sata), " SATA 3.x");
347 		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
348 			snprintf(sata, sizeof(sata), " SATA 2.x");
349 		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
350 			snprintf(sata, sizeof(sata), " SATA 1.x");
351 		else
352 			snprintf(sata, sizeof(sata), " SATA");
353 	} else
354 		sata[0] = 0;
355 	printf("<%s %s> %s%s device\n", product, revision, ata, sata);
356 }
357 
358 void
359 ata_print_ident_short(struct ata_params *ident_data)
360 {
361 	char product[48], revision[16];
362 
363 	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
364 		   sizeof(product));
365 	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
366 		   sizeof(revision));
367 	printf("<%s %s>", product, revision);
368 }
369 
370 void
371 semb_print_ident(struct sep_identify_data *ident_data)
372 {
373 	char vendor[9], product[17], revision[5], fw[5], in[7], ins[5];
374 
375 	cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
376 	cam_strvis(product, ident_data->product_id, 16, sizeof(product));
377 	cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
378 	cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
379 	cam_strvis(in, ident_data->interface_id, 6, sizeof(in));
380 	cam_strvis(ins, ident_data->interface_rev, 4, sizeof(ins));
381 	printf("<%s %s %s %s> SEMB %s %s device\n",
382 	    vendor, product, revision, fw, in, ins);
383 }
384 
385 void
386 semb_print_ident_short(struct sep_identify_data *ident_data)
387 {
388 	char vendor[9], product[17], revision[5], fw[5];
389 
390 	cam_strvis(vendor, ident_data->vendor_id, 8, sizeof(vendor));
391 	cam_strvis(product, ident_data->product_id, 16, sizeof(product));
392 	cam_strvis(revision, ident_data->product_rev, 4, sizeof(revision));
393 	cam_strvis(fw, ident_data->firmware_rev, 4, sizeof(fw));
394 	printf("<%s %s %s %s>", vendor, product, revision, fw);
395 }
396 
397 uint32_t
398 ata_logical_sector_size(struct ata_params *ident_data)
399 {
400 	if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE &&
401 	    (ident_data->pss & ATA_PSS_LSSABOVE512)) {
402 		return (((u_int32_t)ident_data->lss_1 |
403 		    ((u_int32_t)ident_data->lss_2 << 16)) * 2);
404 	}
405 	return (512);
406 }
407 
408 uint64_t
409 ata_physical_sector_size(struct ata_params *ident_data)
410 {
411 	if ((ident_data->pss & ATA_PSS_VALID_MASK) == ATA_PSS_VALID_VALUE) {
412 		if (ident_data->pss & ATA_PSS_MULTLS) {
413 			return ((uint64_t)ata_logical_sector_size(ident_data) *
414 			    (1 << (ident_data->pss & ATA_PSS_LSPPS)));
415 		} else {
416 			return (uint64_t)ata_logical_sector_size(ident_data);
417 		}
418 	}
419 	return (512);
420 }
421 
422 uint64_t
423 ata_logical_sector_offset(struct ata_params *ident_data)
424 {
425 	if ((ident_data->lsalign & 0xc000) == 0x4000) {
426 		return ((uint64_t)ata_logical_sector_size(ident_data) *
427 		    (ident_data->lsalign & 0x3fff));
428 	}
429 	return (0);
430 }
431 
432 void
433 ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
434     uint32_t lba, uint8_t sector_count)
435 {
436 	bzero(&ataio->cmd, sizeof(ataio->cmd));
437 	ataio->cmd.flags = 0;
438 	if (cmd == ATA_READ_DMA ||
439 	    cmd == ATA_READ_DMA_QUEUED ||
440 	    cmd == ATA_WRITE_DMA ||
441 	    cmd == ATA_WRITE_DMA_QUEUED)
442 		ataio->cmd.flags |= CAM_ATAIO_DMA;
443 	ataio->cmd.command = cmd;
444 	ataio->cmd.features = features;
445 	ataio->cmd.lba_low = lba;
446 	ataio->cmd.lba_mid = lba >> 8;
447 	ataio->cmd.lba_high = lba >> 16;
448 	ataio->cmd.device = ATA_DEV_LBA | ((lba >> 24) & 0x0f);
449 	ataio->cmd.sector_count = sector_count;
450 }
451 
452 void
453 ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
454     uint64_t lba, uint16_t sector_count)
455 {
456 
457 	ataio->cmd.flags = CAM_ATAIO_48BIT;
458 	if (cmd == ATA_READ_DMA48 ||
459 	    cmd == ATA_READ_DMA_QUEUED48 ||
460 	    cmd == ATA_READ_STREAM_DMA48 ||
461 	    cmd == ATA_WRITE_DMA48 ||
462 	    cmd == ATA_WRITE_DMA_FUA48 ||
463 	    cmd == ATA_WRITE_DMA_QUEUED48 ||
464 	    cmd == ATA_WRITE_DMA_QUEUED_FUA48 ||
465 	    cmd == ATA_WRITE_STREAM_DMA48 ||
466 	    cmd == ATA_DATA_SET_MANAGEMENT)
467 		ataio->cmd.flags |= CAM_ATAIO_DMA;
468 	ataio->cmd.command = cmd;
469 	ataio->cmd.features = features;
470 	ataio->cmd.lba_low = lba;
471 	ataio->cmd.lba_mid = lba >> 8;
472 	ataio->cmd.lba_high = lba >> 16;
473 	ataio->cmd.device = ATA_DEV_LBA;
474 	ataio->cmd.lba_low_exp = lba >> 24;
475 	ataio->cmd.lba_mid_exp = lba >> 32;
476 	ataio->cmd.lba_high_exp = lba >> 40;
477 	ataio->cmd.features_exp = features >> 8;
478 	ataio->cmd.sector_count = sector_count;
479 	ataio->cmd.sector_count_exp = sector_count >> 8;
480 	ataio->cmd.control = 0;
481 }
482 
483 void
484 ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
485     uint64_t lba, uint16_t sector_count)
486 {
487 
488 	ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_FPDMA;
489 	ataio->cmd.command = cmd;
490 	ataio->cmd.features = sector_count;
491 	ataio->cmd.lba_low = lba;
492 	ataio->cmd.lba_mid = lba >> 8;
493 	ataio->cmd.lba_high = lba >> 16;
494 	ataio->cmd.device = ATA_DEV_LBA;
495 	ataio->cmd.lba_low_exp = lba >> 24;
496 	ataio->cmd.lba_mid_exp = lba >> 32;
497 	ataio->cmd.lba_high_exp = lba >> 40;
498 	ataio->cmd.features_exp = sector_count >> 8;
499 	ataio->cmd.sector_count = 0;
500 	ataio->cmd.sector_count_exp = 0;
501 	ataio->cmd.control = 0;
502 }
503 
504 void
505 ata_reset_cmd(struct ccb_ataio *ataio)
506 {
507 	bzero(&ataio->cmd, sizeof(ataio->cmd));
508 	ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT;
509 	ataio->cmd.control = 0x04;
510 }
511 
512 void
513 ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port)
514 {
515 	bzero(&ataio->cmd, sizeof(ataio->cmd));
516 	ataio->cmd.flags = CAM_ATAIO_NEEDRESULT;
517 	ataio->cmd.command = ATA_READ_PM;
518 	ataio->cmd.features = reg;
519 	ataio->cmd.device = port & 0x0f;
520 }
521 
522 void
523 ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val)
524 {
525 	bzero(&ataio->cmd, sizeof(ataio->cmd));
526 	ataio->cmd.flags = 0;
527 	ataio->cmd.command = ATA_WRITE_PM;
528 	ataio->cmd.features = reg;
529 	ataio->cmd.sector_count = val;
530 	ataio->cmd.lba_low = val >> 8;
531 	ataio->cmd.lba_mid = val >> 16;
532 	ataio->cmd.lba_high = val >> 24;
533 	ataio->cmd.device = port & 0x0f;
534 }
535 
536 void
537 ata_bswap(int8_t *buf, int len)
538 {
539 	u_int16_t *ptr = (u_int16_t*)(buf + len);
540 
541 	while (--ptr >= (u_int16_t*)buf)
542 		*ptr = be16toh(*ptr);
543 }
544 
545 void
546 ata_btrim(int8_t *buf, int len)
547 {
548 	int8_t *ptr;
549 
550 	for (ptr = buf; ptr < buf+len; ++ptr)
551 		if (!*ptr || *ptr == '_')
552 			*ptr = ' ';
553 	for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
554 		*ptr = 0;
555 }
556 
557 void
558 ata_bpack(int8_t *src, int8_t *dst, int len)
559 {
560 	int i, j, blank;
561 
562 	for (i = j = blank = 0 ; i < len; i++) {
563 		if (blank && src[i] == ' ') continue;
564 		if (blank && src[i] != ' ') {
565 			dst[j++] = src[i];
566 			blank = 0;
567 			continue;
568 		}
569 		if (src[i] == ' ') {
570 			blank = 1;
571 			if (i == 0)
572 			continue;
573 		}
574 		dst[j++] = src[i];
575 	}
576 	while (j < len)
577 		dst[j++] = 0x00;
578 }
579 
580 int
581 ata_max_pmode(struct ata_params *ap)
582 {
583     if (ap->atavalid & ATA_FLAG_64_70) {
584 	if (ap->apiomodes & 0x02)
585 	    return ATA_PIO4;
586 	if (ap->apiomodes & 0x01)
587 	    return ATA_PIO3;
588     }
589     if (ap->mwdmamodes & 0x04)
590 	return ATA_PIO4;
591     if (ap->mwdmamodes & 0x02)
592 	return ATA_PIO3;
593     if (ap->mwdmamodes & 0x01)
594 	return ATA_PIO2;
595     if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
596 	return ATA_PIO2;
597     if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
598 	return ATA_PIO1;
599     if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000)
600 	return ATA_PIO0;
601     return ATA_PIO0;
602 }
603 
604 int
605 ata_max_wmode(struct ata_params *ap)
606 {
607     if (ap->mwdmamodes & 0x04)
608 	return ATA_WDMA2;
609     if (ap->mwdmamodes & 0x02)
610 	return ATA_WDMA1;
611     if (ap->mwdmamodes & 0x01)
612 	return ATA_WDMA0;
613     return -1;
614 }
615 
616 int
617 ata_max_umode(struct ata_params *ap)
618 {
619     if (ap->atavalid & ATA_FLAG_88) {
620 	if (ap->udmamodes & 0x40)
621 	    return ATA_UDMA6;
622 	if (ap->udmamodes & 0x20)
623 	    return ATA_UDMA5;
624 	if (ap->udmamodes & 0x10)
625 	    return ATA_UDMA4;
626 	if (ap->udmamodes & 0x08)
627 	    return ATA_UDMA3;
628 	if (ap->udmamodes & 0x04)
629 	    return ATA_UDMA2;
630 	if (ap->udmamodes & 0x02)
631 	    return ATA_UDMA1;
632 	if (ap->udmamodes & 0x01)
633 	    return ATA_UDMA0;
634     }
635     return -1;
636 }
637 
638 int
639 ata_max_mode(struct ata_params *ap, int maxmode)
640 {
641 
642 	if (maxmode == 0)
643 		maxmode = ATA_DMA_MAX;
644 	if (maxmode >= ATA_UDMA0 && ata_max_umode(ap) > 0)
645 		return (min(maxmode, ata_max_umode(ap)));
646 	if (maxmode >= ATA_WDMA0 && ata_max_wmode(ap) > 0)
647 		return (min(maxmode, ata_max_wmode(ap)));
648 	return (min(maxmode, ata_max_pmode(ap)));
649 }
650 
651 char *
652 ata_mode2string(int mode)
653 {
654     switch (mode) {
655     case -1: return "UNSUPPORTED";
656     case 0: return "NONE";
657     case ATA_PIO0: return "PIO0";
658     case ATA_PIO1: return "PIO1";
659     case ATA_PIO2: return "PIO2";
660     case ATA_PIO3: return "PIO3";
661     case ATA_PIO4: return "PIO4";
662     case ATA_WDMA0: return "WDMA0";
663     case ATA_WDMA1: return "WDMA1";
664     case ATA_WDMA2: return "WDMA2";
665     case ATA_UDMA0: return "UDMA0";
666     case ATA_UDMA1: return "UDMA1";
667     case ATA_UDMA2: return "UDMA2";
668     case ATA_UDMA3: return "UDMA3";
669     case ATA_UDMA4: return "UDMA4";
670     case ATA_UDMA5: return "UDMA5";
671     case ATA_UDMA6: return "UDMA6";
672     default:
673 	if (mode & ATA_DMA_MASK)
674 	    return "BIOSDMA";
675 	else
676 	    return "BIOSPIO";
677     }
678 }
679 
680 int
681 ata_string2mode(char *str)
682 {
683 	if (!strcasecmp(str, "PIO0")) return (ATA_PIO0);
684 	if (!strcasecmp(str, "PIO1")) return (ATA_PIO1);
685 	if (!strcasecmp(str, "PIO2")) return (ATA_PIO2);
686 	if (!strcasecmp(str, "PIO3")) return (ATA_PIO3);
687 	if (!strcasecmp(str, "PIO4")) return (ATA_PIO4);
688 	if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0);
689 	if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1);
690 	if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2);
691 	if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0);
692 	if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0);
693 	if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1);
694 	if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1);
695 	if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2);
696 	if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2);
697 	if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3);
698 	if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3);
699 	if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4);
700 	if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4);
701 	if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5);
702 	if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5);
703 	if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6);
704 	if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6);
705 	return (-1);
706 }
707 
708 
709 u_int
710 ata_mode2speed(int mode)
711 {
712 	switch (mode) {
713 	case ATA_PIO0:
714 	default:
715 		return (3300);
716 	case ATA_PIO1:
717 		return (5200);
718 	case ATA_PIO2:
719 		return (8300);
720 	case ATA_PIO3:
721 		return (11100);
722 	case ATA_PIO4:
723 		return (16700);
724 	case ATA_WDMA0:
725 		return (4200);
726 	case ATA_WDMA1:
727 		return (13300);
728 	case ATA_WDMA2:
729 		return (16700);
730 	case ATA_UDMA0:
731 		return (16700);
732 	case ATA_UDMA1:
733 		return (25000);
734 	case ATA_UDMA2:
735 		return (33300);
736 	case ATA_UDMA3:
737 		return (44400);
738 	case ATA_UDMA4:
739 		return (66700);
740 	case ATA_UDMA5:
741 		return (100000);
742 	case ATA_UDMA6:
743 		return (133000);
744 	}
745 }
746 
747 u_int
748 ata_revision2speed(int revision)
749 {
750 	switch (revision) {
751 	case 1:
752 	default:
753 		return (150000);
754 	case 2:
755 		return (300000);
756 	case 3:
757 		return (600000);
758 	}
759 }
760 
761 int
762 ata_speed2revision(u_int speed)
763 {
764 	switch (speed) {
765 	case 0:
766 		return (0);
767 	case 150000:
768 		return (1);
769 	case 300000:
770 		return (2);
771 	case 600000:
772 		return (3);
773 	default:
774 		return (-1);
775 	}
776 }
777 
778 int
779 ata_identify_match(caddr_t identbuffer, caddr_t table_entry)
780 {
781 	struct scsi_inquiry_pattern *entry;
782 	struct ata_params *ident;
783 
784 	entry = (struct scsi_inquiry_pattern *)table_entry;
785 	ident = (struct ata_params *)identbuffer;
786 
787 	if ((cam_strmatch(ident->model, entry->product,
788 			  sizeof(ident->model)) == 0)
789 	 && (cam_strmatch(ident->revision, entry->revision,
790 			  sizeof(ident->revision)) == 0)) {
791 		return (0);
792 	}
793         return (-1);
794 }
795 
796 int
797 ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry)
798 {
799 	struct scsi_static_inquiry_pattern *entry;
800 	struct ata_params *ident;
801 
802 	entry = (struct scsi_static_inquiry_pattern *)table_entry;
803 	ident = (struct ata_params *)identbuffer;
804 
805 	if ((cam_strmatch(ident->model, entry->product,
806 			  sizeof(ident->model)) == 0)
807 	 && (cam_strmatch(ident->revision, entry->revision,
808 			  sizeof(ident->revision)) == 0)) {
809 		return (0);
810 	}
811         return (-1);
812 }
813 
814 void
815 semb_receive_diagnostic_results(struct ccb_ataio *ataio,
816     u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
817     uint8_t tag_action, int pcv, uint8_t page_code,
818     uint8_t *data_ptr, uint16_t length, uint32_t timeout)
819 {
820 
821 	length = min(length, 1020);
822 	length = (length + 3) & ~3;
823 	cam_fill_ataio(ataio,
824 		      retries,
825 		      cbfcnp,
826 		      /*flags*/CAM_DIR_IN,
827 		      tag_action,
828 		      data_ptr,
829 		      length,
830 		      timeout);
831 	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
832 	    pcv ? page_code : 0, 0x02, length / 4);
833 }
834 
835 void
836 semb_send_diagnostic(struct ccb_ataio *ataio,
837     u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
838     uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
839 {
840 
841 	length = min(length, 1020);
842 	length = (length + 3) & ~3;
843 	cam_fill_ataio(ataio,
844 		      retries,
845 		      cbfcnp,
846 		      /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
847 		      tag_action,
848 		      data_ptr,
849 		      length,
850 		      timeout);
851 	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
852 	    length > 0 ? data_ptr[0] : 0, 0x82, length / 4);
853 }
854 
855 void
856 semb_read_buffer(struct ccb_ataio *ataio,
857     u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb*),
858     uint8_t tag_action, uint8_t page_code,
859     uint8_t *data_ptr, uint16_t length, uint32_t timeout)
860 {
861 
862 	length = min(length, 1020);
863 	length = (length + 3) & ~3;
864 	cam_fill_ataio(ataio,
865 		      retries,
866 		      cbfcnp,
867 		      /*flags*/CAM_DIR_IN,
868 		      tag_action,
869 		      data_ptr,
870 		      length,
871 		      timeout);
872 	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
873 	    page_code, 0x00, length / 4);
874 }
875 
876 void
877 semb_write_buffer(struct ccb_ataio *ataio,
878     u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *),
879     uint8_t tag_action, uint8_t *data_ptr, uint16_t length, uint32_t timeout)
880 {
881 
882 	length = min(length, 1020);
883 	length = (length + 3) & ~3;
884 	cam_fill_ataio(ataio,
885 		      retries,
886 		      cbfcnp,
887 		      /*flags*/length ? CAM_DIR_OUT : CAM_DIR_NONE,
888 		      tag_action,
889 		      data_ptr,
890 		      length,
891 		      timeout);
892 	ata_28bit_cmd(ataio, ATA_SEP_ATTN,
893 	    length > 0 ? data_ptr[0] : 0, 0x80, length / 4);
894 }
895 
896