Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Rework struct ata_command to support LBA28 and LBA48-pro...



details:   https://anonhg.NetBSD.org/src/rev/87aae63af82f
branches:  trunk
changeset: 773008:87aae63af82f
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Tue Jan 24 20:04:07 2012 +0000

description:
Rework struct ata_command to support LBA28 and LBA48-protocol commands.
Implement 28- and 48-bit command issuance and parameter read-back in the
various ATA host drivers. Add LBA28-protocol support to ATAIOCCOMMAND ioctl.

diffstat:

 sys/dev/ata/atavar.h       |  30 +++++++++-----
 sys/dev/ata/satafis_subr.c |  89 +++++++++++++++++++++++++++++++--------------
 sys/dev/ata/satafisreg.h   |  44 +++++++++++-----------
 sys/dev/ata/wd.c           |  23 +++++++----
 sys/dev/ic/mvsata.c        |  64 +++++++++++++++++++++++++++-----
 sys/dev/ic/wdc.c           |  77 ++++++++++++++++++++++++++++++---------
 sys/sys/ataio.h            |   3 +-
 7 files changed, 230 insertions(+), 100 deletions(-)

diffs (truncated from 554 to 300 lines):

diff -r 027e1583a8b7 -r 87aae63af82f sys/dev/ata/atavar.h
--- a/sys/dev/ata/atavar.h      Tue Jan 24 20:03:36 2012 +0000
+++ b/sys/dev/ata/atavar.h      Tue Jan 24 20:04:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: atavar.h,v 1.83 2011/10/29 18:43:58 jakllsch Exp $     */
+/*     $NetBSD: atavar.h,v 1.84 2012/01/24 20:04:07 jakllsch Exp $     */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.
@@ -238,18 +238,24 @@
  * (which need multiple interrupts per commands).
  */
 struct ata_command {
-       u_int8_t r_command;     /* Parameters to upload to registers */
-       u_int8_t r_head;
-       u_int16_t r_cyl;
-       u_int8_t r_sector;
-       u_int8_t r_count;
-       u_int8_t r_features;
-       u_int8_t r_st_bmask;    /* status register mask to wait for before
+       /* ATA parameters */
+       uint64_t r_lba;         /* before & after */
+       uint16_t r_count;       /* before & after */
+       union {
+               uint16_t r_features; /* before */
+               uint8_t r_error; /* after */
+       };
+       union {
+               uint8_t r_command; /* before */
+               uint8_t r_status; /* after */
+       };
+       uint8_t r_device;       /* before & after */
+
+       uint8_t r_st_bmask;     /* status register mask to wait for before
                                   command */
-       u_int8_t r_st_pmask;    /* status register mask to wait for after
+       uint8_t r_st_pmask;     /* status register mask to wait for after
                                   command */
-       u_int8_t r_error;       /* error register after command done */
-       volatile u_int16_t flags;
+       volatile uint16_t flags;
 
 #define AT_READ     0x0001 /* There is data to read */
 #define AT_WRITE    0x0002 /* There is data to write (excl. with AT_READ) */
@@ -263,6 +269,8 @@
 #define AT_RESET    0x0400 /* command terminated by channel reset */
 #define AT_GONE     0x0800 /* command terminated because device is gone */
 #define AT_READREG  0x1000 /* Read registers on completion */
+#define AT_LBA      0x2000 /* LBA28 */
+#define AT_LBA48    0x4000 /* LBA48 */
 
        int timeout;            /* timeout (in ms) */
        void *data;             /* Data buffer address */
diff -r 027e1583a8b7 -r 87aae63af82f sys/dev/ata/satafis_subr.c
--- a/sys/dev/ata/satafis_subr.c        Tue Jan 24 20:03:36 2012 +0000
+++ b/sys/dev/ata/satafis_subr.c        Tue Jan 24 20:04:07 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: satafis_subr.c,v 1.5 2010/04/07 17:51:16 jakllsch Exp $ */
+/* $NetBSD: satafis_subr.c,v 1.6 2012/01/24 20:04:07 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2009 Jonathan A. Kollasch.
@@ -51,7 +51,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: satafis_subr.c,v 1.5 2010/04/07 17:51:16 jakllsch Exp $");
+__KERNEL_RCSID(0, "$NetBSD: satafis_subr.c,v 1.6 2012/01/24 20:04:07 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -69,17 +69,32 @@
 void
 satafis_rhd_construct_cmd(struct ata_command *ata_c, uint8_t *fis)
 {
+
        memset(fis, 0, RHD_FISLEN);
 
        fis[fis_type] = RHD_FISTYPE;
        fis[rhd_c] = RHD_C;
        fis[rhd_command] = ata_c->r_command;
-       fis[rhd_features] = ata_c->r_features;
-       fis[rhd_sector] = ata_c->r_sector;
-       fis[rhd_cyl_lo] = ata_c->r_cyl & 0xff;
-       fis[rhd_cyl_hi] = (ata_c->r_cyl >> 8) & 0xff;
-       fis[rhd_dh] = ata_c->r_head & 0x0f;
-       fis[rhd_seccnt] = ata_c->r_count;
+       fis[rhd_features0] = (ata_c->r_features >> 0) & 0xff;
+
+       fis[rhd_lba0] = (ata_c->r_lba >> 0) & 0xff;
+       fis[rhd_lba1] = (ata_c->r_lba >> 8) & 0xff;
+       fis[rhd_lba2] = (ata_c->r_lba >> 16) & 0xff;
+       if ((ata_c->flags & AT_LBA48) != 0) {
+               fis[rhd_dh] = WDSD_LBA;
+               fis[rhd_lba3] = (ata_c->r_lba >> 24) & 0xff;
+               fis[rhd_lba4] = (ata_c->r_lba >> 32) & 0xff;
+               fis[rhd_lba5] = (ata_c->r_lba >> 40) & 0xff;
+               fis[rhd_features1] = (ata_c->r_features >> 8) & 0xff;
+       } else {
+               fis[rhd_dh] = ((ata_c->r_lba >> 24) & 0x0f) |
+                   (((ata_c->flags & AT_LBA) != 0) ? WDSD_LBA : 0);
+       }
+
+       fis[rhd_count0] = (ata_c->r_count >> 0) & 0xff;
+       if ((ata_c->flags & AT_LBA48) != 0) {
+               fis[rhd_count1] = (ata_c->r_count >> 8) & 0xff;
+       }
 }
 
 void
@@ -101,41 +116,45 @@
                fis[rhd_command] =
                    (ata_bio->flags & ATA_READ) ? WDCC_READDMA : WDCC_WRITEDMA;
        }
-       fis[rhd_sector] = ata_bio->blkno & 0xff;
-       fis[rhd_cyl_lo] = (ata_bio->blkno >> 8) & 0xff;
-       fis[rhd_cyl_hi] = (ata_bio->blkno >> 16) & 0xff;
-       if (ata_bio->flags & ATA_LBA48) {
+
+       fis[rhd_lba0] = (ata_bio->blkno >> 0) & 0xff;
+       fis[rhd_lba1] = (ata_bio->blkno >> 8) & 0xff;
+       fis[rhd_lba2] = (ata_bio->blkno >> 16) & 0xff;
+       if ((ata_bio->flags & ATA_LBA48) != 0) {
                fis[rhd_dh] = WDSD_LBA;
-               fis[rhd_sector_exp] = (ata_bio->blkno >> 24) & 0xff;
-               fis[rhd_cyl_lo_exp] = (ata_bio->blkno >> 32) & 0xff;
-               fis[rhd_cyl_hi_exp] = (ata_bio->blkno >> 40) & 0xff;
+               fis[rhd_lba3] = (ata_bio->blkno >> 24) & 0xff;
+               fis[rhd_lba4] = (ata_bio->blkno >> 32) & 0xff;
+               fis[rhd_lba5] = (ata_bio->blkno >> 40) & 0xff;
        } else {
-               fis[rhd_dh] = ((ata_bio->blkno >> 24) & 0x0f) | WDSD_LBA;
+               fis[rhd_dh] = ((ata_bio->blkno >> 24) & 0x0f) |
+                   (((ata_bio->flags & ATA_LBA) != 0) ? WDSD_LBA : 0);
        }
-       fis[rhd_seccnt] = nblks & 0xff;
-       fis[rhd_seccnt_exp] = (ata_bio->flags & ATA_LBA48) ?
-           ((nblks >> 8) & 0xff) : 0;
+
+       fis[rhd_count0] = nblks & 0xff;
+       if ((ata_bio->flags & ATA_LBA48) != 0) {
+               fis[rhd_count1] = (nblks >> 8) & 0xff;
+       }
 }
 
 #if NATAPIBUS > 0
 void
 satafis_rhd_construct_atapi(struct ata_xfer *xfer, uint8_t *fis)
 {
+
        memset(fis, 0, RHD_FISLEN);
 
        fis[fis_type] = RHD_FISTYPE;
        fis[rhd_c] = RHD_C;
        fis[rhd_command] = ATAPI_PKT_CMD;
-       fis[rhd_features] = (xfer->c_flags & C_DMA) ?
+       fis[rhd_features0] = (xfer->c_flags & C_DMA) ?
            ATAPI_PKT_CMD_FTRE_DMA : 0;
-
-       return;
 }
 #endif /* NATAPIBUS */
 
 void
 satafis_rdh_parse(struct ata_channel *chp, const uint8_t *fis)
 {
+
        chp->ch_status = fis[rdh_status];
        chp->ch_error = fis[rdh_error];
 }
@@ -143,11 +162,25 @@
 void
 satafis_rdh_cmd_readreg(struct ata_command *ata_c, const uint8_t *fis)
 {
-       ata_c->r_command = fis[rdh_status];
-       ata_c->r_features = fis[rdh_error];
+
+       ata_c->r_lba = (uint64_t)fis[rdh_lba0] << 0;
+       ata_c->r_lba |= (uint64_t)fis[rdh_lba1] << 8;
+       ata_c->r_lba |= (uint64_t)fis[rdh_lba2] << 16;
+       if ((ata_c->flags & AT_LBA48) != 0) {
+               ata_c->r_lba |= (uint64_t)fis[rdh_lba3] << 24;
+               ata_c->r_lba |= (uint64_t)fis[rdh_lba4] << 32;
+               ata_c->r_lba |= (uint64_t)fis[rdh_lba5] << 40;
+       } else {
+               ata_c->r_lba |= (uint64_t)(fis[rdh_dh] & 0x0f) << 24;
+       }
+
+       ata_c->r_count = fis[rdh_count0] << 0;
+       if ((ata_c->flags & AT_LBA48) != 0) {
+               ata_c->r_count |= fis[rdh_count1] << 8;
+       }
+
        ata_c->r_error = fis[rdh_error];
-       ata_c->r_sector = fis[rdh_sector];
-       ata_c->r_cyl = fis[rdh_cyl_hi] << 8 | fis[rdh_cyl_lo];
-       ata_c->r_head = fis[rdh_dh];
-       ata_c->r_count = fis[rdh_seccnt];
+       ata_c->r_status = fis[rdh_status];
+
+       ata_c->r_device = fis[rdh_dh] & 0xf0;
 }
diff -r 027e1583a8b7 -r 87aae63af82f sys/dev/ata/satafisreg.h
--- a/sys/dev/ata/satafisreg.h  Tue Jan 24 20:03:36 2012 +0000
+++ b/sys/dev/ata/satafisreg.h  Tue Jan 24 20:04:07 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: satafisreg.h,v 1.3 2011/11/02 18:41:58 jakllsch Exp $ */
+/* $NetBSD: satafisreg.h,v 1.4 2012/01/24 20:04:07 jakllsch Exp $ */
 
 /*
  * Copyright (c) 2009, 2010 Jonathan A. Kollasch.
@@ -34,18 +34,18 @@
 #define RHD_FISLEN 20
 #define rhd_c 1 /* Command bit and PM port */
 #define RHD_C 0x80
-#define rhd_command 2 /* wd_command */
-#define rhd_features 3 /* wd_precomp */
-#define rhd_sector 4 /* wd_sector */
-#define rhd_cyl_lo 5 /* wd_cyl_lo */
-#define rhd_cyl_hi 6 /* wd_cyl_hi */
-#define rhd_dh 7 /* wd_sdh */
-#define rhd_sector_exp 8
-#define rhd_cyl_lo_exp 9
-#define rhd_cyl_hi_exp 10
-#define rhd_features_exp 11
-#define rhd_seccnt 12
-#define rhd_seccnt_exp 13
+#define rhd_command 2
+#define rhd_features0 3
+#define rhd_lba0 4
+#define rhd_lba1 5
+#define rhd_lba2 6
+#define rhd_dh 7
+#define rhd_lba3 8
+#define rhd_lba4 9
+#define rhd_lba5 10
+#define rhd_features1 11
+#define rhd_count0 12
+#define rhd_count1 13
 #define rhd_control 15
 
 #define RDH_FISTYPE 0x34
@@ -54,15 +54,15 @@
 #define RDH_I 0x40
 #define rdh_status 2
 #define rdh_error 3
-#define rdh_sector 4 /* wd_sector */
-#define rdh_cyl_lo 5 /* wd_cyl_lo */
-#define rdh_cyl_hi 6 /* wd_cyl_hi */
-#define rdh_dh 7 /* wd_sdh */
-#define rdh_sector_exp 8
-#define rdh_cyl_lo_exp 9
-#define rdh_cyl_hi_exp 10
-#define rdh_seccnt 12
-#define rdh_seccnt_exp 13
+#define rdh_lba0 4
+#define rdh_lba1 5
+#define rdh_lba2 6
+#define rdh_dh 7
+#define rdh_lba3 8
+#define rdh_lba4 9
+#define rdh_lba5 10
+#define rdh_count0 12
+#define rdh_count1 13
 
 #define SDB_FISTYPE 0xA1
 #define SDB_FISLEN 8
diff -r 027e1583a8b7 -r 87aae63af82f sys/dev/ata/wd.c
--- a/sys/dev/ata/wd.c  Tue Jan 24 20:03:36 2012 +0000
+++ b/sys/dev/ata/wd.c  Tue Jan 24 20:04:07 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: wd.c,v 1.390 2011/11/25 13:55:40 joerg Exp $ */
+/*     $NetBSD: wd.c,v 1.391 2012/01/24 20:04:07 jakllsch Exp $ */
 
 /*
  * Copyright (c) 1998, 2001 Manuel Bouyer.  All rights reserved.
@@ -54,7 +54,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.390 2011/11/25 13:55:40 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.391 2012/01/24 20:04:07 jakllsch Exp $");
 
 #include "opt_ata.h"
 
@@ -2068,13 +2068,16 @@
        if (wi->wi_atareq.flags & ATACMD_READREG)
                ata_c.flags |= AT_READREG;
 
+       if ((wi->wi_atareq.flags & ATACMD_LBA) != 0)
+               ata_c.flags |= AT_LBA;
+
        ata_c.flags |= AT_WAIT;
 
        ata_c.timeout = wi->wi_atareq.timeout;
        ata_c.r_command = wi->wi_atareq.command;
-       ata_c.r_head = wi->wi_atareq.head & 0x0f;
-       ata_c.r_cyl = wi->wi_atareq.cylinder;
-       ata_c.r_sector = wi->wi_atareq.sec_num;
+       ata_c.r_lba = ((wi->wi_atareq.head & 0x0f) << 24) |



Home | Main Index | Thread Index | Old Index