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