ata_all.c revision 297933
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: head/sys/cam/ata/ata_all.c 297933 2016-04-13 20:10:06Z scottl $");
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
58int
59ata_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
71char *
72ata_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
211char *
212ata_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
230void
231ata_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
241char *
242ata_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
260int
261ata_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 */
277int
278ata_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 */
291int
292ata_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
321void
322ata_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
358void
359ata_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
370void
371semb_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
385void
386semb_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
397uint32_t
398ata_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
408uint64_t
409ata_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
422uint64_t
423ata_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
432void
433ata_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
452void
453ata_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
483void
484ata_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
504void
505ata_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
512void
513ata_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
522void
523ata_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
536void
537ata_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
545void
546ata_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
557void
558ata_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
580int
581ata_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
604int
605ata_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
616int
617ata_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
638int
639ata_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
651char *
652ata_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
680int
681ata_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
709u_int
710ata_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
747u_int
748ata_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
761int
762ata_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
778int
779ata_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
796int
797ata_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
814void
815semb_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
835void
836semb_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
855void
856semb_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
876void
877semb_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