Page 1 of 47

Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 11:19 am
by fvdw
Here we continue from general nas-central topic to develop support for 5bign_v2

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 11:44 am
by Jocko
Jocko wrote:Yes, you have...

look at your last fdisk output :
Code: Select all
Disk /dev/sdb: 500.1 GB, 500107862016 bytes
256 heads, 63 sectors/track, 60563 cylinders
Units = cylinders of 16128 * 512 = 8257536 bytes

   Device Boot      Start         End      Blocks  Id System
/dev/sdb1               1       60564   488386583+ ee EFI GPT
Ooops, I forgot this disk has been formated by using fvdw-sl console.

So yes, your other disks must not be gpt disks. If their disk system is ntfs is not a good new because write performance won't be fast...

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 11:54 am
by Mijzelf
fvdw wrote:I think the disk with the fvdw-sl firmware must be the last one
also I need to have a look to u-boot. This 5big2 has a funny start up sequence.
Code: Select all
         setenv("boot_disk10","disk ${kernel_addr} 5:${primaryPart}; setenv rootfs /dev/sde7;");
         setenv("boot_disk9","if disk ${kernel_addr} 6:${primaryPart}; then setenv rootfs /dev/sdd7; else run boot_disk10; fi");
         setenv("boot_disk8","if disk ${kernel_addr} 1:${primaryPart}; then setenv rootfs /dev/sdc7; else run boot_disk9; fi");
         setenv("boot_disk7","if disk ${kernel_addr} 2:${primaryPart}; then setenv rootfs /dev/sdb7; else run boot_disk8; fi");
         setenv("boot_disk6","if disk ${kernel_addr} 3:${primaryPart}; then setenv rootfs /dev/sda7; else run boot_disk7; fi");
         setenv("boot_disk5","if disk ${kernel_addr} 5:${secondaryPart}; then setenv rootfs /dev/sde7; else run boot_disk6; fi");
         setenv("boot_disk4","if disk ${kernel_addr} 6:${secondaryPart}; then setenv rootfs /dev/sdd7; else run boot_disk5; fi");
         setenv("boot_disk3","if disk ${kernel_addr} 1:${secondaryPart}; then setenv rootfs /dev/sdc7; else run boot_disk4; fi");
         setenv("boot_disk2","if disk ${kernel_addr} 2:${secondaryPart}; then setenv rootfs /dev/sdb7; else run boot_disk3; fi");
         setenv("boot_disk1","if disk ${kernel_addr} 3:${secondaryPart}; then setenv rootfs /dev/sda7; else run boot_disk2; fi");

We need to understand this to avoid the need to use fvdw-sl console to start up the nas
We should have only one disk with a partition 6 and a kernel and ensure that this one is detected gets id sda for the kernel
You should read it from bottom up. It first checks sda10, then sdb10, ...., then sda7, sdb7, ....
The sdx10 partitions can contain an 'upgrade kernel', which has an initrd which can add a snap, or create a new rootfs, bootfs, or even flash a new u-boot. (But I haven't seen a u-boot containing capsule yet.)

I agree that it's strange that u-boot seems to have another disk order than the linux kernel does. BTW, according to smallnetbuilder.com the box uses a Marvell 88SM4140 SATA multiplier.

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 2:29 pm
by fvdw
yep I know about partition 10 and 7

the device number is strange 3,2,1,6,5

device 3 seems to slot 1, device 2 is slot 2 (from test with Draftmancorp 5bin2) so I suppose slot 3 is device 1, dev 6 is slot 4 and dev 5 slot 5 (note that there is no device 4)

The funny thing is that if you have two disk (in slot 1 and 2) then sda is device 2 (slot2), if you have one disk in slot 1 sda is device 3 (slot1)

Logically you would think that the last disk inserted is sda. Annoying then that u-boot gives as root a partition from another disk if you have more then one disk inserted
For instance two disks sda will be slot 2 so device 2, it then will find a kernel in partition 6 of this disk but assigns as bootarg for root /dev/sdb7 being the disk in slot 1 :hammerhead :crazy

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 3:41 pm
by fvdw
I just had a look in the kernel output in the trials we made

it seems to be caused by a difference in the kernel

Lacie disk is slot 1 (=device 3) and the fvdw-sl disk in slot 2 (=device 2)
Output lacie kernel
[ 5.900000] sd 0:2:0:0: [sdb] 976773168 512-byte logical blocks: (500 GB/465GiB)
[ 5.940000] sd 0:3:0:0: [sda] 976773168 512-byte logical blocks: (500 GB/465GiB)
so it sees slot 1 as sda and slot 2 as sdb

The fvdw-sl kernel sees slot 2 as sda and slot 1 as sdb :scratch

This causes a problem as we need to give u-boot another kernel command line, but the solution for that will be use the backdoor in lacie U-boot :mrgreen:

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 3:55 pm
by Mijzelf
From the Lacie GPL sources:
lacie/common.c:
Code: Select all
/**
 *      lacie_get_disk_num - could be called by the SCSI layer sd.c or
 *      by a low level SCSI driver (SATA driver for example).
 *      This function allow to get the case disk number associated with
 *      a SCSI disk.
 *      @sdp: scsi device
 *
 *      Returns "disk number" or -1
 *
 **/
int lacie_get_disk_num(struct scsi_device *sdp)
{
        int i;
        struct lacie_disk *disk;

        if (unlikely(!lacie_disk_map))
                return -1;

        for (i = 0; i < lacie_disk_map->num_disks; i++) {
                disk = &lacie_disk_map->disks[i];
                if (sdp->channel == disk->channel && sdp->id == disk->id &&
                        sdp->host->host_no == disk->host_no) {
                        return i;
                }
        }
        return -1;
}

arch/arm/mach-feroceon-kw/lacie/net5big_v2-setup.c:
Code: Select all
static struct lacie_disk net5big_v2_disks[] = {
        {
                .host_no = 0,
                .channel = 3,
                .id      = 0,
                .letter  = 'a',
        },
        {
                .host_no = 0,
                .channel = 2,
                .id      = 0,
                .letter  = 'b',
        },
        {
                .host_no = 0,
                .channel = 1,
                .id      = 0,
                .letter  = 'c',
        },
        {
                .host_no = 1,
                .channel = 2,
                .id      = 0,
                .letter  = 'd',
        },
        {
                .host_no = 1,
                .channel = 1,
                .id      = 0,
                .letter  = 'e',
        },
};
So it seems the Lacie kernel hardcodes the device name against the slot number.

In your case, I *think* it should be possible to do the reverse. As you know sda means host 0 channel 3, it should be possible to find the corresponding disk in /sys, somehow. But I suppose it's easier to just use a tag. The system is supposed to be on partition 1, when I remember well? You could just mount them one by one, and the one containing an executable /sbin/init is used. And maybe you have a more discriminating file, somewhere.

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 4:19 pm
by fvdw
yes that could be an approach but the nas database uses the drive letters to mount them. I f you then take out disk everything becomes a mess.
In the vanilla kernel I found this in the setup file for the 5big2 (for the 2big2 the same file is used)
It defines a structure
Code: Select all
static struct mv_sata_platform_data netxbig_v2_sata_data = {
   .n_ports   = 2,
};

That is used in the init function at boot
Code: Select all
   kirkwood_sata_init(&netxbig_v2_sata_data);


The sata_init function look likes this

Code: Select all
void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
{
   kirkwood_clk_ctrl |= CGC_SATA0;
   if (sata_data->n_ports > 1)
      kirkwood_clk_ctrl |= CGC_SATA1;
   sata_data->dram = &kirkwood_mbus_dram_info;
   kirkwood_sata.dev.platform_data = sata_data;
   platform_device_register(&kirkwood_sata);
}


Maybe there is a way to add the code lacie used to hard code the device names against slot name :thinking

It could be that it should be added in netxbig_v2_sata_data in the main setup file for the netxbig_v2 or be added in the platfom info of common.c file but changing that will affect all kirkwood kernels so not a good idea
Code: Select all
/*****************************************************************************
 * SATA
 ****************************************************************************/
static struct resource kirkwood_sata_resources[] = {
   {
      .name   = "sata base",
      .start   = SATA_PHYS_BASE,
      .end   = SATA_PHYS_BASE + 0x5000 - 1,
      .flags   = IORESOURCE_MEM,
   }, {
      .name   = "sata irq",
      .start   = IRQ_KIRKWOOD_SATA,
      .end   = IRQ_KIRKWOOD_SATA,
      .flags   = IORESOURCE_IRQ,
   },
};

static struct platform_device kirkwood_sata = {
   .name      = "sata_mv",
   .id      = 0,
   .dev      = {
      .coherent_dma_mask   = 0xffffffff,
   },
   .num_resources   = ARRAY_SIZE(kirkwood_sata_resources),
   .resource   = kirkwood_sata_resources,
};

but then how to pass this to the sata driver...

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 5:07 pm
by fvdw
seems the vanilla kernel defines names in sd.c (drivers/scsi)

Code: Select all
/**
 *   sd_format_disk_name - format disk name
 *   @prefix: name prefix - ie. "sd" for SCSI disks
 *   @index: index of the disk to format name for
 *   @buf: output buffer
 *   @buflen: length of the output buffer
 *
 *   SCSI disk names starts at sda.  The 26th device is sdz and the
 *   27th is sdaa.  The last one for two lettered suffix is sdzz
 *   which is followed by sdaaa.
 *
 *   This is basically 26 base counting with one extra 'nil' entry
 *   at the beginning from the second digit on and can be
 *   determined using similar method as 26 base conversion with the
 *   index shifted -1 after each digit is computed.
 *
 *   CONTEXT:
 *   Don't care.
 *
 *   RETURNS:
 *   0 on success, -errno on failure.
 */
static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
{
   const int base = 'z' - 'a' + 1;
   char *begin = buf + strlen(prefix);
   char *end = buf + buflen;
   char *p;
   int unit;

   p = end - 1;
   *p = '\0';
   unit = base;
   do {
      if (p == begin)
         return -EINVAL;
      *--p = 'a' + (index % unit);
      index = (index / unit) - 1;
   } while (index >= 0);

   memmove(begin, p, end - p);
   memcpy(buf, prefix, strlen(prefix));

   return 0;
}

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 5:30 pm
by Mijzelf
Lacie injected it in a different function:
drivers/scsi/sd.c:
Code: Select all
#if defined(CONFIG_LACIE_SCSI_DISK_RENAMING)
extern int lacie_get_sd_name(struct scsi_device *sdp, char *prefix_letter, u32 *index);
#endif
<snip>

static int sd_probe(struct device *dev)
{
<snip>
        sdkp->index = index;

#if defined(CONFIG_LACIE_SCSI_DISK_RENAMING)
        lacie_get_sd_name(sdp, &prefix[1], &index);
#endif

        error = sd_format_disk_name(prefix, index, gd->disk_name,
                                    DISK_NAME_LEN);
 


Why would it become a mess? Now the bootloader specifies a disk, and if you in initrd can translate it to the actual disk, there is nothing messy? Unless you want the bootdisk always to be sda. In that case you can specify the disk should always be in slot 1, or you'll have to patch the kernel to read the cmdline, and make it sda.

Re: Lacie 5bign_v2 support

PostPosted: Sat May 11, 2013 6:51 pm
by fvdw
the vanilla kernel has a slightly different code in that routine (sd.c . funtion static int sd_probe(struct device *dev) )
Code: Select all
   if (index >= SD_MAX_DISKS) {
      error = -ENODEV;
      sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n");
      goto out_free_index;
   }

   error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
   if (error)
      goto out_free_index;

   sdkp->device = sdp;
   sdkp->driver = &sd_template;
   sdkp->disk = gd;
   sdkp->index = index;
   atomic_set(&sdkp->openers, 0);


Seems not to be too difficult to add it, I will give it a try

About the mess, well the firmware uses in the code sda to do some mounts, so we must be sure that the disk it uses to start the firmware is always sda. (of course we code adapt the code of the firmware but I do not prefer that) Furthermore it will mount the different disk using the driver letter. If you then increase or reduce the number of disk the letter doesn't correspond anymore with right disk and that will make more problems in the database, for instance for defined shares and location.
If slot 5 would be always the first letter it get assigned then the sda problem could be solved by putting the drive with firmware always in slot 5 and use modified u-boot command to pass right bootargs (using the backdoor).
But it will be too much things to remember if the renaming works it is sorted. Although the vanilla kernel has one setup file for 5big2 and 2big2 But that can be solved as well by making two. Like I did for nwsp2 lite. Adapting sd.c however will affect the operation for other devices as well it must only the function for 5big2 or 2big2