ata_all.c revision 203421
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 203421 2010-02-03 10:06:03Z mav $");
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	switch (cmd->command) {
76	case 0x00: return ("NOP");
77	case 0x03: return ("CFA_REQUEST_EXTENDED_ERROR");
78	case 0x06:
79		switch (cmd->features) {
80	        case 0x01: return ("DSM TRIM");
81	        }
82	        return "DSM";
83	case 0x08: return ("DEVICE_RESET");
84	case 0x20: return ("READ");
85	case 0x24: return ("READ48");
86	case 0x25: return ("READ_DMA48");
87	case 0x26: return ("READ_DMA_QUEUED48");
88	case 0x27: return ("READ_NATIVE_MAX_ADDRESS48");
89	case 0x29: return ("READ_MUL48");
90	case 0x2a: return ("READ_STREAM_DMA48");
91	case 0x2b: return ("READ_STREAM48");
92	case 0x2f: return ("READ_LOG_EXT");
93	case 0x30: return ("WRITE");
94	case 0x34: return ("WRITE48");
95	case 0x35: return ("WRITE_DMA48");
96	case 0x36: return ("WRITE_DMA_QUEUED48");
97	case 0x37: return ("SET_MAX_ADDRESS48");
98	case 0x39: return ("WRITE_MUL48");
99	case 0x3a: return ("WRITE_STREAM_DMA48");
100	case 0x3b: return ("WRITE_STREAM48");
101	case 0x3d: return ("WRITE_DMA_FUA48");
102	case 0x3e: return ("WRITE_DMA_QUEUED_FUA48");
103	case 0x3f: return ("WRITE_LOG_EXT");
104	case 0x40: return ("READ_VERIFY");
105	case 0x42: return ("READ_VERIFY48");
106	case 0x51: return ("CONFIGURE_STREAM");
107	case 0x60: return ("READ_FPDMA_QUEUED");
108	case 0x61: return ("WRITE_FPDMA_QUEUED");
109	case 0x70: return ("SEEK");
110	case 0x87: return ("CFA_TRANSLATE_SECTOR");
111	case 0x90: return ("EXECUTE_DEVICE_DIAGNOSTIC");
112	case 0x92: return ("DOWNLOAD_MICROCODE");
113	case 0xa0: return ("PACKET");
114	case 0xa1: return ("ATAPI_IDENTIFY");
115	case 0xa2: return ("SERVICE");
116	case 0xb0: return ("SMART");
117	case 0xb1: return ("DEVICE CONFIGURATION");
118	case 0xc0: return ("CFA_ERASE");
119	case 0xc4: return ("READ_MUL");
120	case 0xc5: return ("WRITE_MUL");
121	case 0xc6: return ("SET_MULTI");
122	case 0xc7: return ("READ_DMA_QUEUED");
123	case 0xc8: return ("READ_DMA");
124	case 0xca: return ("WRITE_DMA");
125	case 0xcc: return ("WRITE_DMA_QUEUED");
126	case 0xcd: return ("CFA_WRITE_MULTIPLE_WITHOUT_ERASE");
127	case 0xce: return ("WRITE_MUL_FUA48");
128	case 0xd1: return ("CHECK_MEDIA_CARD_TYPE");
129	case 0xda: return ("GET_MEDIA_STATUS");
130	case 0xde: return ("MEDIA_LOCK");
131	case 0xdf: return ("MEDIA_UNLOCK");
132	case 0xe0: return ("STANDBY_IMMEDIATE");
133	case 0xe1: return ("IDLE_IMMEDIATE");
134	case 0xe2: return ("STANDBY");
135	case 0xe3: return ("IDLE");
136	case 0xe4: return ("READ_BUFFER/PM");
137	case 0xe5: return ("CHECK_POWER_MODE");
138	case 0xe6: return ("SLEEP");
139	case 0xe7: return ("FLUSHCACHE");
140	case 0xe8: return ("WRITE_PM");
141	case 0xea: return ("FLUSHCACHE48");
142	case 0xec: return ("ATA_IDENTIFY");
143	case 0xed: return ("MEDIA_EJECT");
144	case 0xef:
145		switch (cmd->features) {
146	        case 0x03: return ("SETFEATURES SET TRANSFER MODE");
147	        case 0x02: return ("SETFEATURES ENABLE WCACHE");
148	        case 0x82: return ("SETFEATURES DISABLE WCACHE");
149	        case 0x06: return ("SETFEATURES ENABLE PUIS");
150	        case 0x86: return ("SETFEATURES DISABLE PUIS");
151	        case 0x07: return ("SETFEATURES SPIN-UP");
152	        case 0xaa: return ("SETFEATURES ENABLE RCACHE");
153	        case 0x55: return ("SETFEATURES DISABLE RCACHE");
154	        }
155	        return "SETFEATURES";
156	case 0xf1: return ("SECURITY_SET_PASSWORD");
157	case 0xf2: return ("SECURITY_UNLOCK");
158	case 0xf3: return ("SECURITY_ERASE_PREPARE");
159	case 0xf4: return ("SECURITY_ERASE_UNIT");
160	case 0xf5: return ("SECURITY_FREE_LOCK");
161	case 0xf6: return ("SECURITY DISABLE PASSWORD");
162	case 0xf8: return ("READ_NATIVE_MAX_ADDRESS");
163	case 0xf9: return ("SET_MAX_ADDRESS");
164	}
165	return "UNKNOWN";
166}
167
168char *
169ata_cmd_string(struct ata_cmd *cmd, char *cmd_string, size_t len)
170{
171
172	snprintf(cmd_string, len, "%02x %02x %02x %02x "
173	    "%02x %02x %02x %02x %02x %02x %02x %02x",
174	    cmd->command, cmd->features,
175	    cmd->lba_low, cmd->lba_mid, cmd->lba_high, cmd->device,
176	    cmd->lba_low_exp, cmd->lba_mid_exp, cmd->lba_high_exp,
177	    cmd->features_exp, cmd->sector_count, cmd->sector_count_exp);
178
179	return(cmd_string);
180}
181
182char *
183ata_res_string(struct ata_res *res, char *res_string, size_t len)
184{
185
186	snprintf(res_string, len, "%02x %02x %02x %02x "
187	    "%02x %02x %02x %02x %02x %02x %02x",
188	    res->status, res->error,
189	    res->lba_low, res->lba_mid, res->lba_high, res->device,
190	    res->lba_low_exp, res->lba_mid_exp, res->lba_high_exp,
191	    res->sector_count, res->sector_count_exp);
192
193	return(res_string);
194}
195
196/*
197 * ata_command_sbuf() returns 0 for success and -1 for failure.
198 */
199int
200ata_command_sbuf(struct ccb_ataio *ataio, struct sbuf *sb)
201{
202	char cmd_str[(12 * 3) + 1];
203
204	sbuf_printf(sb, "%s. ACB: %s",
205	    ata_op_string(&ataio->cmd),
206	    ata_cmd_string(&ataio->cmd, cmd_str, sizeof(cmd_str)));
207
208	return(0);
209}
210
211/*
212 * ata_status_abuf() returns 0 for success and -1 for failure.
213 */
214int
215ata_status_sbuf(struct ccb_ataio *ataio, struct sbuf *sb)
216{
217
218	sbuf_printf(sb, "ATA status: %02x (%s%s%s%s%s%s%s%s)",
219	    ataio->res.status,
220	    (ataio->res.status & 0x80) ? "BSY " : "",
221	    (ataio->res.status & 0x40) ? "DRDY " : "",
222	    (ataio->res.status & 0x20) ? "DF " : "",
223	    (ataio->res.status & 0x10) ? "SERV " : "",
224	    (ataio->res.status & 0x08) ? "DRQ " : "",
225	    (ataio->res.status & 0x04) ? "CORR " : "",
226	    (ataio->res.status & 0x02) ? "IDX " : "",
227	    (ataio->res.status & 0x01) ? "ERR" : "");
228	if (ataio->res.status & 1) {
229	    sbuf_printf(sb, ", error: %02x (%s%s%s%s%s%s%s%s)",
230		ataio->res.error,
231		(ataio->res.error & 0x80) ? "ICRC " : "",
232		(ataio->res.error & 0x40) ? "UNC " : "",
233		(ataio->res.error & 0x20) ? "MC " : "",
234		(ataio->res.error & 0x10) ? "IDNF " : "",
235		(ataio->res.error & 0x08) ? "MCR " : "",
236		(ataio->res.error & 0x04) ? "ABRT " : "",
237		(ataio->res.error & 0x02) ? "NM " : "",
238		(ataio->res.error & 0x01) ? "ILI" : "");
239	}
240
241	return(0);
242}
243
244/*
245 * ata_res_sbuf() returns 0 for success and -1 for failure.
246 */
247int
248ata_res_sbuf(struct ccb_ataio *ataio, struct sbuf *sb)
249{
250	char res_str[(11 * 3) + 1];
251
252	sbuf_printf(sb, "RES: %s",
253	    ata_res_string(&ataio->res, res_str, sizeof(res_str)));
254
255	return(0);
256}
257
258void
259ata_print_ident(struct ata_params *ident_data)
260{
261	char product[48], revision[16];
262
263	cam_strvis(product, ident_data->model, sizeof(ident_data->model),
264		   sizeof(product));
265	cam_strvis(revision, ident_data->revision, sizeof(ident_data->revision),
266		   sizeof(revision));
267	printf("<%s %s> %s-%d",
268	    product, revision,
269	    (ident_data->config & ATA_PROTO_ATAPI) ? "ATAPI" : "ATA",
270	    ata_version(ident_data->version_major));
271	if (ident_data->satacapabilities && ident_data->satacapabilities != 0xffff) {
272		if (ident_data->satacapabilities & ATA_SATA_GEN3)
273			printf(" SATA 3.x");
274		else if (ident_data->satacapabilities & ATA_SATA_GEN2)
275			printf(" SATA 2.x");
276		else if (ident_data->satacapabilities & ATA_SATA_GEN1)
277			printf(" SATA 1.x");
278		else
279			printf(" SATA");
280	}
281	printf(" device\n");
282}
283
284uint32_t
285ata_logical_sector_size(struct ata_params *ident_data)
286{
287	if ((ident_data->pss & 0xc000) == 0x4000 &&
288	    (ident_data->pss & ATA_PSS_LSSABOVE512)) {
289		return ((u_int32_t)ident_data->lss_1 |
290		    ((u_int32_t)ident_data->lss_2 << 16));
291	}
292	return (512);
293}
294
295uint64_t
296ata_physical_sector_size(struct ata_params *ident_data)
297{
298	if ((ident_data->pss & 0xc000) == 0x4000 &&
299	    (ident_data->pss & ATA_PSS_MULTLS)) {
300		return ((uint64_t)ata_logical_sector_size(ident_data) *
301		    (1 << (ident_data->pss & ATA_PSS_LSPPS)));
302	}
303	return (512);
304}
305
306uint64_t
307ata_logical_sector_offset(struct ata_params *ident_data)
308{
309	if ((ident_data->lsalign & 0xc000) == 0x4000) {
310		return ((uint64_t)ata_logical_sector_size(ident_data) *
311		    (ident_data->lsalign & 0x3fff));
312	}
313	return (0);
314}
315
316void
317ata_28bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint8_t features,
318    uint32_t lba, uint8_t sector_count)
319{
320	bzero(&ataio->cmd, sizeof(ataio->cmd));
321	ataio->cmd.flags = 0;
322	if (cmd == ATA_READ_DMA ||
323	    cmd == ATA_READ_DMA_QUEUED ||
324	    cmd == ATA_WRITE_DMA ||
325	    cmd == ATA_WRITE_DMA_QUEUED)
326		ataio->cmd.flags |= CAM_ATAIO_DMA;
327	ataio->cmd.command = cmd;
328	ataio->cmd.features = features;
329	ataio->cmd.lba_low = lba;
330	ataio->cmd.lba_mid = lba >> 8;
331	ataio->cmd.lba_high = lba >> 16;
332	ataio->cmd.device = 0x40 | ((lba >> 24) & 0x0f);
333	ataio->cmd.sector_count = sector_count;
334}
335
336void
337ata_48bit_cmd(struct ccb_ataio *ataio, uint8_t cmd, uint16_t features,
338    uint64_t lba, uint16_t sector_count)
339{
340	bzero(&ataio->cmd, sizeof(ataio->cmd));
341	ataio->cmd.flags = CAM_ATAIO_48BIT;
342	if (cmd == ATA_READ_DMA48 ||
343	    cmd == ATA_READ_DMA_QUEUED48 ||
344	    cmd == ATA_READ_STREAM_DMA48 ||
345	    cmd == ATA_WRITE_DMA48 ||
346	    cmd == ATA_WRITE_DMA_FUA48 ||
347	    cmd == ATA_WRITE_DMA_QUEUED48 ||
348	    cmd == ATA_WRITE_DMA_QUEUED_FUA48 ||
349	    cmd == ATA_WRITE_STREAM_DMA48 ||
350	    cmd == ATA_DATA_SET_MANAGEMENT)
351		ataio->cmd.flags |= CAM_ATAIO_DMA;
352	ataio->cmd.command = cmd;
353	ataio->cmd.features = features;
354	ataio->cmd.lba_low = lba;
355	ataio->cmd.lba_mid = lba >> 8;
356	ataio->cmd.lba_high = lba >> 16;
357	ataio->cmd.device = 0x40;
358	ataio->cmd.lba_low_exp = lba >> 24;
359	ataio->cmd.lba_mid_exp = lba >> 32;
360	ataio->cmd.lba_high_exp = lba >> 40;
361	ataio->cmd.features_exp = features >> 8;
362	ataio->cmd.sector_count = sector_count;
363	ataio->cmd.sector_count_exp = sector_count >> 8;
364}
365
366void
367ata_ncq_cmd(struct ccb_ataio *ataio, uint8_t cmd,
368    uint64_t lba, uint16_t sector_count)
369{
370	bzero(&ataio->cmd, sizeof(ataio->cmd));
371	ataio->cmd.flags = CAM_ATAIO_48BIT | CAM_ATAIO_FPDMA;
372	ataio->cmd.command = cmd;
373	ataio->cmd.features = sector_count;
374	ataio->cmd.lba_low = lba;
375	ataio->cmd.lba_mid = lba >> 8;
376	ataio->cmd.lba_high = lba >> 16;
377	ataio->cmd.device = 0x40;
378	ataio->cmd.lba_low_exp = lba >> 24;
379	ataio->cmd.lba_mid_exp = lba >> 32;
380	ataio->cmd.lba_high_exp = lba >> 40;
381	ataio->cmd.features_exp = sector_count >> 8;
382}
383
384void
385ata_reset_cmd(struct ccb_ataio *ataio)
386{
387	bzero(&ataio->cmd, sizeof(ataio->cmd));
388	ataio->cmd.flags = CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT;
389	ataio->cmd.control = 0x04;
390}
391
392void
393ata_pm_read_cmd(struct ccb_ataio *ataio, int reg, int port)
394{
395	bzero(&ataio->cmd, sizeof(ataio->cmd));
396	ataio->cmd.flags = CAM_ATAIO_NEEDRESULT;
397	ataio->cmd.command = ATA_READ_PM;
398	ataio->cmd.features = reg;
399	ataio->cmd.device = port & 0x0f;
400}
401
402void
403ata_pm_write_cmd(struct ccb_ataio *ataio, int reg, int port, uint32_t val)
404{
405	bzero(&ataio->cmd, sizeof(ataio->cmd));
406	ataio->cmd.flags = 0;
407	ataio->cmd.command = ATA_WRITE_PM;
408	ataio->cmd.features = reg;
409	ataio->cmd.sector_count = val;
410	ataio->cmd.lba_low = val >> 8;
411	ataio->cmd.lba_mid = val >> 16;
412	ataio->cmd.lba_high = val >> 24;
413	ataio->cmd.device = port & 0x0f;
414}
415
416void
417ata_bswap(int8_t *buf, int len)
418{
419	u_int16_t *ptr = (u_int16_t*)(buf + len);
420
421	while (--ptr >= (u_int16_t*)buf)
422		*ptr = be16toh(*ptr);
423}
424
425void
426ata_btrim(int8_t *buf, int len)
427{
428	int8_t *ptr;
429
430	for (ptr = buf; ptr < buf+len; ++ptr)
431		if (!*ptr || *ptr == '_')
432			*ptr = ' ';
433	for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
434		*ptr = 0;
435}
436
437void
438ata_bpack(int8_t *src, int8_t *dst, int len)
439{
440	int i, j, blank;
441
442	for (i = j = blank = 0 ; i < len; i++) {
443		if (blank && src[i] == ' ') continue;
444		if (blank && src[i] != ' ') {
445			dst[j++] = src[i];
446			blank = 0;
447			continue;
448		}
449		if (src[i] == ' ') {
450			blank = 1;
451			if (i == 0)
452			continue;
453		}
454		dst[j++] = src[i];
455	}
456	while (j < len)
457		dst[j++] = 0x00;
458}
459
460int
461ata_max_pmode(struct ata_params *ap)
462{
463    if (ap->atavalid & ATA_FLAG_64_70) {
464	if (ap->apiomodes & 0x02)
465	    return ATA_PIO4;
466	if (ap->apiomodes & 0x01)
467	    return ATA_PIO3;
468    }
469    if (ap->mwdmamodes & 0x04)
470	return ATA_PIO4;
471    if (ap->mwdmamodes & 0x02)
472	return ATA_PIO3;
473    if (ap->mwdmamodes & 0x01)
474	return ATA_PIO2;
475    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x200)
476	return ATA_PIO2;
477    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x100)
478	return ATA_PIO1;
479    if ((ap->retired_piomode & ATA_RETIRED_PIO_MASK) == 0x000)
480	return ATA_PIO0;
481    return ATA_PIO0;
482}
483
484int
485ata_max_wmode(struct ata_params *ap)
486{
487    if (ap->mwdmamodes & 0x04)
488	return ATA_WDMA2;
489    if (ap->mwdmamodes & 0x02)
490	return ATA_WDMA1;
491    if (ap->mwdmamodes & 0x01)
492	return ATA_WDMA0;
493    return -1;
494}
495
496int
497ata_max_umode(struct ata_params *ap)
498{
499    if (ap->atavalid & ATA_FLAG_88) {
500	if (ap->udmamodes & 0x40)
501	    return ATA_UDMA6;
502	if (ap->udmamodes & 0x20)
503	    return ATA_UDMA5;
504	if (ap->udmamodes & 0x10)
505	    return ATA_UDMA4;
506	if (ap->udmamodes & 0x08)
507	    return ATA_UDMA3;
508	if (ap->udmamodes & 0x04)
509	    return ATA_UDMA2;
510	if (ap->udmamodes & 0x02)
511	    return ATA_UDMA1;
512	if (ap->udmamodes & 0x01)
513	    return ATA_UDMA0;
514    }
515    return -1;
516}
517
518int
519ata_max_mode(struct ata_params *ap, int maxmode)
520{
521
522	if (maxmode == 0)
523		maxmode = ATA_DMA_MAX;
524	if (maxmode >= ATA_UDMA0 && ata_max_umode(ap) > 0)
525		return (min(maxmode, ata_max_umode(ap)));
526	if (maxmode >= ATA_WDMA0 && ata_max_wmode(ap) > 0)
527		return (min(maxmode, ata_max_wmode(ap)));
528	return (min(maxmode, ata_max_pmode(ap)));
529}
530
531char *
532ata_mode2string(int mode)
533{
534    switch (mode) {
535    case -1: return "UNSUPPORTED";
536    case 0: return "NONE";
537    case ATA_PIO0: return "PIO0";
538    case ATA_PIO1: return "PIO1";
539    case ATA_PIO2: return "PIO2";
540    case ATA_PIO3: return "PIO3";
541    case ATA_PIO4: return "PIO4";
542    case ATA_WDMA0: return "WDMA0";
543    case ATA_WDMA1: return "WDMA1";
544    case ATA_WDMA2: return "WDMA2";
545    case ATA_UDMA0: return "UDMA0";
546    case ATA_UDMA1: return "UDMA1";
547    case ATA_UDMA2: return "UDMA2";
548    case ATA_UDMA3: return "UDMA3";
549    case ATA_UDMA4: return "UDMA4";
550    case ATA_UDMA5: return "UDMA5";
551    case ATA_UDMA6: return "UDMA6";
552    default:
553	if (mode & ATA_DMA_MASK)
554	    return "BIOSDMA";
555	else
556	    return "BIOSPIO";
557    }
558}
559
560int
561ata_string2mode(char *str)
562{
563	if (!strcasecmp(str, "PIO0")) return (ATA_PIO0);
564	if (!strcasecmp(str, "PIO1")) return (ATA_PIO1);
565	if (!strcasecmp(str, "PIO2")) return (ATA_PIO2);
566	if (!strcasecmp(str, "PIO3")) return (ATA_PIO3);
567	if (!strcasecmp(str, "PIO4")) return (ATA_PIO4);
568	if (!strcasecmp(str, "WDMA0")) return (ATA_WDMA0);
569	if (!strcasecmp(str, "WDMA1")) return (ATA_WDMA1);
570	if (!strcasecmp(str, "WDMA2")) return (ATA_WDMA2);
571	if (!strcasecmp(str, "UDMA0")) return (ATA_UDMA0);
572	if (!strcasecmp(str, "UDMA16")) return (ATA_UDMA0);
573	if (!strcasecmp(str, "UDMA1")) return (ATA_UDMA1);
574	if (!strcasecmp(str, "UDMA25")) return (ATA_UDMA1);
575	if (!strcasecmp(str, "UDMA2")) return (ATA_UDMA2);
576	if (!strcasecmp(str, "UDMA33")) return (ATA_UDMA2);
577	if (!strcasecmp(str, "UDMA3")) return (ATA_UDMA3);
578	if (!strcasecmp(str, "UDMA44")) return (ATA_UDMA3);
579	if (!strcasecmp(str, "UDMA4")) return (ATA_UDMA4);
580	if (!strcasecmp(str, "UDMA66")) return (ATA_UDMA4);
581	if (!strcasecmp(str, "UDMA5")) return (ATA_UDMA5);
582	if (!strcasecmp(str, "UDMA100")) return (ATA_UDMA5);
583	if (!strcasecmp(str, "UDMA6")) return (ATA_UDMA6);
584	if (!strcasecmp(str, "UDMA133")) return (ATA_UDMA6);
585	return (-1);
586}
587
588
589u_int
590ata_mode2speed(int mode)
591{
592	switch (mode) {
593	case ATA_PIO0:
594	default:
595		return (3300);
596	case ATA_PIO1:
597		return (5200);
598	case ATA_PIO2:
599		return (8300);
600	case ATA_PIO3:
601		return (11100);
602	case ATA_PIO4:
603		return (16700);
604	case ATA_WDMA0:
605		return (4200);
606	case ATA_WDMA1:
607		return (13300);
608	case ATA_WDMA2:
609		return (16700);
610	case ATA_UDMA0:
611		return (16700);
612	case ATA_UDMA1:
613		return (25000);
614	case ATA_UDMA2:
615		return (33300);
616	case ATA_UDMA3:
617		return (44400);
618	case ATA_UDMA4:
619		return (66700);
620	case ATA_UDMA5:
621		return (100000);
622	case ATA_UDMA6:
623		return (133000);
624	}
625}
626
627u_int
628ata_revision2speed(int revision)
629{
630	switch (revision) {
631	case 1:
632	default:
633		return (150000);
634	case 2:
635		return (300000);
636	case 3:
637		return (600000);
638	}
639}
640
641int
642ata_speed2revision(u_int speed)
643{
644	switch (speed) {
645	case 0:
646		return (0);
647	case 150000:
648		return (1);
649	case 300000:
650		return (2);
651	case 600000:
652		return (3);
653	default:
654		return (-1);
655	}
656}
657
658int
659ata_identify_match(caddr_t identbuffer, caddr_t table_entry)
660{
661	struct scsi_inquiry_pattern *entry;
662	struct ata_params *ident;
663
664	entry = (struct scsi_inquiry_pattern *)table_entry;
665	ident = (struct ata_params *)identbuffer;
666
667	if ((cam_strmatch(ident->model, entry->product,
668			  sizeof(ident->model)) == 0)
669	 && (cam_strmatch(ident->revision, entry->revision,
670			  sizeof(ident->revision)) == 0)) {
671		return (0);
672	}
673        return (-1);
674}
675
676int
677ata_static_identify_match(caddr_t identbuffer, caddr_t table_entry)
678{
679	struct scsi_static_inquiry_pattern *entry;
680	struct ata_params *ident;
681
682	entry = (struct scsi_static_inquiry_pattern *)table_entry;
683	ident = (struct ata_params *)identbuffer;
684
685	if ((cam_strmatch(ident->model, entry->product,
686			  sizeof(ident->model)) == 0)
687	 && (cam_strmatch(ident->revision, entry->revision,
688			  sizeof(ident->revision)) == 0)) {
689		return (0);
690	}
691        return (-1);
692}
693