NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/39395: ataraid(4): JMicron RAID support
The following reply was made to PR kern/39395; it has been noted by GNATS.
From: Juan RP <xtraeme%gmail.com@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc:
Subject: Re: kern/39395: ataraid(4): JMicron RAID support
Date: Sun, 24 Aug 2008 02:17:05 +0200
Previous uuencoded patch was corrupted. Here's the patch again
and some dmesg spam as well.
$ dmesg|grep -E '(ataraid|ld0)'
ataraid0: found 1 RAID volume
ld0 at ataraid0 vendtype 4 unit 0: JMicron ATA RAID-1 array
ld0: 233 GB, 30514 cyl, 255 head, 63 sec, 512 bytes/sect x 490209280 sectors
$
Index: ata_raid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raid.c,v
retrieving revision 1.30
diff -b -u -p -r1.30 ata_raid.c
--- ata_raid.c 20 Aug 2008 15:00:34 -0000 1.30
+++ ata_raid.c 23 Aug 2008 14:33:57 -0000
@@ -116,9 +116,10 @@ ata_raid_type_name(u_int type)
"Adaptec",
"VIA V-RAID",
"nVidia",
+ "JMicron"
};
- if (type < sizeof(ata_raid_type_names) / sizeof(ata_raid_type_names[0]))
+ if (type < __arraycount(ata_raid_type_names))
return (ata_raid_type_names[type]);
return (NULL);
@@ -247,6 +248,8 @@ ata_raid_check_component(device_t self)
return;
if (ata_raid_read_config_nvidia(sc) == 0)
return;
+ if (ata_raid_read_config_jmicron(sc) == 0)
+ return;
}
struct ataraid_array_info *
Index: ata_raid_jmicron.c
===================================================================
RCS file: ata_raid_jmicron.c
diff -N ata_raid_jmicron.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ata_raid_jmicron.c 23 Aug 2008 14:33:57 -0000
@@ -0,0 +1,255 @@
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2000-2008 S_ren Schmidt <sos%FreeBSD.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification, immediately at the beginning of the file.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Support for parsing JMicron Technology RAID controller configuration
blocks.
+ *
+ * Adapted to NetBSD by Juan Romero Pardines (xtraeme%gmail.org@localhost).
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/buf.h>
+#include <sys/bufq.h>
+#include <sys/conf.h>
+#include <sys/device.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/fcntl.h>
+#include <sys/malloc.h>
+#include <sys/vnode.h>
+#include <sys/kauth.h>
+
+#include <miscfs/specfs/specdev.h>
+
+#include <dev/ata/atareg.h>
+#include <dev/ata/atavar.h>
+#include <dev/ata/wdvar.h>
+
+#include <dev/ata/ata_raidreg.h>
+#include <dev/ata/ata_raidvar.h>
+
+#ifdef ATA_RAID_DEBUG
+#define DPRINTF(x) printf x
+#else
+#define DPRINTF(x) /* nothing */
+#endif
+
+#ifdef ATA_RAID_DEBUG
+static const char *
+ata_raid_jmicron_type(int type)
+{
+ static char buffer[16];
+
+ switch (type) {
+ case JM_T_RAID0:
+ return "RAID0";
+ case JM_T_RAID1:
+ return "RAID1";
+ case JM_T_RAID01:
+ return "RAID0+1";
+ case JM_T_RAID5:
+ return "RAID5";
+ case JM_T_JBOD:
+ return "JBOD";
+ default:
+ sprintf(buffer, "UNKNOWN 0x%02x", type);
+ return buffer;
+ }
+}
+
+static void
+ata_raid_jmicron_print_info(struct jmicron_raid_conf *info)
+{
+ int i;
+
+ printf("****** ATA JMicron Technology Corp Metadata ******\n");
+ printf("signature %.2s\n", info->signature);
+ printf("version 0x%04x\n", info->version);
+ printf("checksum 0x%04x\n", info->checksum);
+ printf("disk_id 0x%08x\n", info->disk_id);
+ printf("offset 0x%08x\n", info->offset);
+ printf("disk_sectors_low 0x%08x\n", info->disk_sectors_low);
+ printf("disk_sectors_high 0x%08x\n", info->disk_sectors_high);
+ printf("name %.16s\n", info->name);
+ printf("type %s\n",
+ ata_raid_jmicron_type(info->type));
+ printf("stripe_shift %d\n", info->stripe_shift);
+ printf("flags 0x%04x\n", info->flags);
+ printf("spare:\n");
+ for (i = 0; i < 2 && info->spare[i]; i++)
+ printf(" %d 0x%08x\n", i, info->spare[i]);
+ printf("disks:\n");
+ for (i = 0; i < 8 && info->disks[i]; i++)
+ printf(" %d 0x%08x\n", i, info->disks[i]);
+ printf("=================================================\n");
+}
+#endif
+
+int
+ata_raid_read_config_jmicron(struct wd_softc *sc)
+{
+ struct atabus_softc *atabus;
+ struct jmicron_raid_conf *info;
+ struct vnode *vp;
+ struct ataraid_array_info *aai;
+ struct ataraid_disk_info *adi;
+ uint64_t disk_size;
+ uint32_t drive;
+ uint16_t checksum, *ptr;
+ int bmajor, error, count, disk, total_disks;
+ dev_t dev;
+
+ info = malloc(sizeof(*info), M_DEVBUF, M_WAITOK|M_ZERO);
+
+ bmajor = devsw_name2blk(device_xname(sc->sc_dev), NULL, 0);
+
+ /* Get a vnode for the raw partition of this disk. */
+ dev = MAKEDISKDEV(bmajor, device_unit(sc->sc_dev), RAW_PART);
+ error = bdevvp(dev, &vp);
+ if (error)
+ goto out;
+
+ error = VOP_OPEN(vp, FREAD, NOCRED);
+ if (error) {
+ vput(vp);
+ goto out;
+ }
+
+ error = ata_raid_config_block_rw(vp, JMICRON_LBA(sc), info,
+ sizeof(*info), B_READ);
+ VOP_CLOSE(vp, FREAD, NOCRED);
+ vput(vp);
+ if (error) {
+ DPRINTF(("%s: error %d reading JMicron config block\n",
+ device_xname(sc->sc_dev), error));
+ goto out;
+ }
+
+ /* Check for JMicron signature. */
+ if (strncmp(info->signature, JMICRON_MAGIC, 2)) {
+ DPRINTF(("%s: JMicron RAID signature check failed\n",
+ device_xname(sc->sc_dev)));
+ error = ESRCH;
+ goto out;
+ }
+
+ /* calculate checksum and compare for valid */
+ for (checksum = 0, ptr = (uint16_t *)info, count = 0;
+ count < 64; count++)
+ checksum += *ptr++;
+ if (checksum) {
+ DPRINTF(("%s: JMicron checksum failed\n",
+ device_xname(sc->sc_dev)));
+ error = ESRCH;
+ goto out;
+ }
+
+#ifdef ATA_RAID_DEBUG
+ ata_raid_jmicron_print_info(info);
+#endif
+
+ /*
+ * Lookup or allocate a new array info structure for
+ * this array.
+ */
+ aai = ata_raid_get_array_info(ATA_RAID_TYPE_JMICRON, 0);
+
+ for (total_disks = 0, disk = 0; disk < JM_MAX_DISKS; disk++)
+ if (info->disks[disk])
+ total_disks++;
+ if (total_disks == 0)
+ goto out;
+
+ aai->aai_status = AAI_S_READY;
+
+ switch (info->type) {
+ case JM_T_RAID0:
+ aai->aai_level = AAI_L_RAID0;
+ aai->aai_width = total_disks;
+ break;
+ case JM_T_RAID1:
+ aai->aai_level = AAI_L_RAID1;
+ aai->aai_width = 1;
+ break;
+ case JM_T_RAID01:
+ aai->aai_level = AAI_L_RAID0 | AAI_L_RAID1;
+ aai->aai_width = total_disks / 2;
+ break;
+ case JM_T_JBOD:
+ aai->aai_level = AAI_L_SPAN;
+ aai->aai_width = total_disks;
+ break;
+ default:
+ DPRINTF(("%s: unknown JMicron RAID type 0x%02x\n",
+ sc->sc_dev->dv_xname, info->type));
+ error = EINVAL;
+ goto out;
+ }
+
+ disk_size = (info->disk_sectors_high << 16) + info->disk_sectors_low;
+ aai->aai_type = ATA_RAID_TYPE_JMICRON;
+ aai->aai_generation = 0;
+ aai->aai_capacity = disk_size * aai->aai_width;
+ aai->aai_interleave = 2 << info->stripe_shift;
+ aai->aai_ndisks = total_disks;
+ aai->aai_heads = 255;
+ aai->aai_sectors = 63;
+ aai->aai_cylinders =
+ aai->aai_capacity / (aai->aai_heads * aai->aai_sectors);
+ aai->aai_offset = info->offset * 16;
+ aai->aai_reserved = 0;
+
+ atabus = device_private(device_parent(sc->sc_dev));
+ drive = atabus->sc_chan->ch_channel;
+ if (drive >= aai->aai_ndisks) {
+ DPRINTF(("%s: drive number %d doesn't make sense within "
+ "%d-disk array\n", device_xname(sc->sc_dev),
+ drive, aai->aai_ndisks));
+ error = EINVAL;
+ goto out;
+ }
+
+ if (info->disks[drive] == info->disk_id) {
+ adi = &aai->aai_disks[drive];
+ adi->adi_dev = sc->sc_dev;
+ adi->adi_status = ADI_S_ONLINE | ADI_S_ASSIGNED;
+ adi->adi_sectors = aai->aai_capacity;
+ adi->adi_compsize = disk_size;
+ }
+
+ error = 0;
+
+ out:
+ free(info, M_DEVBUF);
+ return error;
+}
Index: ata_raidreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raidreg.h,v
retrieving revision 1.6
diff -b -u -p -r1.6 ata_raidreg.h
--- ata_raidreg.h 20 Aug 2008 15:00:34 -0000 1.6
+++ ata_raidreg.h 23 Aug 2008 14:33:58 -0000
@@ -255,4 +255,42 @@ struct nvidia_raid_conf {
u_int32_t filler[98];
} __packed;
+/* JMicron Technology Corp Metadata */
+#define JMICRON_LBA(wd) ((wd)->sc_capacity - 1)
+#define JM_MAX_DISKS 8
+
+struct jmicron_raid_conf {
+ uint8_t signature[2];
+#define JMICRON_MAGIC "JM"
+ uint16_t version;
+#define JMICRON_VERSION 0x0001
+ uint16_t checksum;
+ uint8_t filler_1[10];
+ uint32_t disk_id;
+ uint32_t offset;
+ uint32_t disk_sectors_high;
+ uint16_t disk_sectors_low;
+ uint8_t filler_2[2];
+ uint8_t name[16];
+ uint8_t type;
+#define JM_T_RAID0 0
+#define JM_T_RAID1 1
+#define JM_T_RAID01 2
+#define JM_T_JBOD 3
+#define JM_T_RAID5 5
+ uint8_t stripe_shift;
+ uint16_t flags;
+#define JM_F_READY 0x0001
+#define JM_F_BOOTABLE 0x0002
+#define JM_F_BAD 0x0004
+#define JM_F_ACTIVE 0x0010
+#define JM_F_UNSYNC 0x0020
+#define JM_F_NEWEST 0x0040
+ uint8_t filler_3[4];
+ uint32_t spare[2];
+ uint32_t disks[JM_MAX_DISKS];
+ uint8_t filler_4[32];
+ uint8_t filler_5[384];
+};
+
#endif /* _DEV_PCI_PCIIDE_PROMISE_RAID_H_ */
Index: ata_raidvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raidvar.h,v
retrieving revision 1.6
diff -b -u -p -r1.6 ata_raidvar.h
--- ata_raidvar.h 20 Aug 2008 15:00:34 -0000 1.6
+++ ata_raidvar.h 23 Aug 2008 14:33:58 -0000
@@ -52,7 +52,8 @@
#define ATA_RAID_TYPE_ADAPTEC 1
#define ATA_RAID_TYPE_VIA 2
#define ATA_RAID_TYPE_NVIDIA 3
-#define ATA_RAID_TYPE_MAX 3
+#define ATA_RAID_TYPE_JMICRON 4
+#define ATA_RAID_TYPE_MAX 4
/*
* Max # of disks supported by a single array. This is limited by
@@ -82,7 +83,7 @@ struct ataraid_array_info {
u_int aai_type; /* array type */
u_int aai_arrayno; /* array number */
int aai_level; /* RAID level */
- int aai_generation; /* config generaion # */
+ int aai_generation; /* config generation # */
int aai_status; /* array status */
/* Geometry info. */
@@ -134,4 +135,7 @@ int ata_raid_read_config_via(struct wd_s
/* nVidia MediaShield support */
int ata_raid_read_config_nvidia(struct wd_softc *);
+/* JMicron RAID support */
+int ata_raid_read_config_jmicron(struct wd_softc *);
+
#endif /* _DEV_ATA_ATA_RAIDVAR_H_ */
Index: files.ata
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/files.ata,v
retrieving revision 1.17
diff -b -u -p -r1.17 files.ata
--- files.ata 20 Aug 2008 15:00:34 -0000 1.17
+++ files.ata 23 Aug 2008 14:33:58 -0000
@@ -22,6 +22,7 @@ file dev/ata/ata_raid_promise.c ataraid
file dev/ata/ata_raid_adaptec.c ataraid
file dev/ata/ata_raid_nvidia.c ataraid
file dev/ata/ata_raid_via.c ataraid
+file dev/ata/ata_raid_jmicron.c ataraid
attach ld at ataraid with ld_ataraid
file dev/ata/ld_ataraid.c ld_ataraid
Index: ataraid.4
===================================================================
RCS file: /cvsroot/src/share/man/man4/ataraid.4,v
retrieving revision 1.8
diff -b -u -p -r1.8 ataraid.4
--- ataraid.4 23 Aug 2008 07:26:55 -0000 1.8
+++ ataraid.4 23 Aug 2008 14:37:41 -0000
@@ -55,6 +55,8 @@ Adaptec HostRAID (found in Intel 6300ESB
Via V-RAID (found in many VIA-based motherboards)
.It
nVidia MediaShield
+.It
+JMicron RAID
.El
.Sh SEE ALSO
.Xr ld 4
Home |
Main Index |
Thread Index |
Old Index