summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1999-11-05 04:32:04 +0000
committerConstantine Sapuntzakis <csapuntz@cvs.openbsd.org>1999-11-05 04:32:04 +0000
commitdd3245a8cdcba7e6e4945135cea5bfa58a75b8e4 (patch)
tree4b5a65694e21b7fb9a99128383eca928cc42aa47
parentb71dff44533542f83559ae0f4dcefa7fa5379ba1 (diff)
Fix ata_get_params on big endian platforms.
We have diverged from NetBSD in that wdc_exec_xfer no longer automatically swaps.
-rw-r--r--sys/dev/ata/ata.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/sys/dev/ata/ata.c b/sys/dev/ata/ata.c
index 2594d801665..dc90a40f60b 100644
--- a/sys/dev/ata/ata.c
+++ b/sys/dev/ata/ata.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ata.c,v 1.2 1999/08/05 00:12:09 niklas Exp $ */
+/* $OpenBSD: ata.c,v 1.3 1999/11/05 04:32:03 csapuntz Exp $ */
/* $NetBSD: ata.c,v 1.9 1999/04/15 09:41:09 bouyer Exp $ */
/*
* Copyright (c) 1998 Manuel Bouyer. All rights reserved.
@@ -57,6 +57,8 @@ extern int wdcdebug_mask; /* init'ed in wdc.c */
#define WDCDEBUG_PRINT(args, level)
#endif
+#define ATAPARAMS_SIZE 512
+
/* Get the disk's parameters */
int
ata_get_params(drvp, flags, prms)
@@ -64,17 +66,15 @@ ata_get_params(drvp, flags, prms)
u_int8_t flags;
struct ataparams *prms;
{
- char tb[DEV_BSIZE];
+ char tb[ATAPARAMS_SIZE];
struct wdc_command wdc_c;
-#if BYTE_ORDER == LITTLE_ENDIAN
int i;
u_int16_t *p;
-#endif
WDCDEBUG_PRINT(("wdc_ata_get_parms\n"), DEBUG_FUNCS);
- bzero(tb, DEV_BSIZE);
+ bzero(tb, sizeof(tb));
bzero(prms, sizeof(struct ataparams));
bzero(&wdc_c, sizeof(struct wdc_command));
@@ -93,7 +93,7 @@ ata_get_params(drvp, flags, prms)
}
wdc_c.flags = AT_READ | flags;
wdc_c.data = tb;
- wdc_c.bcount = DEV_BSIZE;
+ wdc_c.bcount = ATAPARAMS_SIZE;
{
int ret;
@@ -106,9 +106,24 @@ ata_get_params(drvp, flags, prms)
if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
return CMD_ERR;
} else {
+#if BYTE_ORDER == BIG_ENDIAN
+ /* All the fields in the params structure are 16-bit
+ integers except for the ID strings which are char
+ strings. The 16-bit integers are currently in
+ memory in little-endian, regardless of architecture.
+ So, they need to be swapped on big-endian architectures
+ before they are accessed through the ataparams structure.
+
+ The swaps below avoid touching the char strings.
+ */
+
+ swap16_multi((u_int16_t *)tb, 10);
+ swap16_multi((u_int16_t *)tb + 20, 3);
+ swap16_multi((u_int16_t *)tb + 47, ATAPARAMS_SIZE / 2 - 47);
+#endif
/* Read in parameter block. */
bcopy(tb, prms, sizeof(struct ataparams));
-#if BYTE_ORDER == LITTLE_ENDIAN
+
/*
* Shuffle string byte order.
* ATAPI Mitsumi and NEC drives don't need this.
@@ -122,17 +137,17 @@ ata_get_params(drvp, flags, prms)
return 0;
for (i = 0; i < sizeof(prms->atap_model); i += 2) {
p = (u_short *)(prms->atap_model + i);
- *p = ntohs(*p);
+ *p = swap16(*p);
}
for (i = 0; i < sizeof(prms->atap_serial); i += 2) {
p = (u_short *)(prms->atap_serial + i);
- *p = ntohs(*p);
+ *p = swap16(*p);
}
for (i = 0; i < sizeof(prms->atap_revision); i += 2) {
p = (u_short *)(prms->atap_revision + i);
- *p = ntohs(*p);
+ *p = swap16(*p);
}
-#endif
+
return CMD_OK;
}
}