linux-mips
[Top] [All Lists]

Re: Problem with large IDE disk on a MIPS bigendian system.

To: linux-mips@oss.sgi.com
Subject: Re: Problem with large IDE disk on a MIPS bigendian system.
From: Carsten Langgaard <carstenl@mips.com>
Date: Fri, 20 Apr 2001 16:15:59 +0200
References: <3AE01EFF.850580E4@mips.com>
Sender: owner-linux-mips@oss.sgi.com
I should probably point out that the fix change the addressing mode on
large disks (>8GB) supporting LBA mode.
So you want be able to run on a system which was created by an older
kernel, but it probably didn't work properly anyway before the fix.
This only count for bigendian systems on large disks.

/Carsten


Carsten Langgaard wrote:

> I have noticed that a bigendian kernel can't quite handled IDE disk,
> which is larger than 8GB and support LBA mode (logical addressing mode).
>
> The IDE driver read some of the data incorrectly and therefore doesn't
> recognize that the drive support LBA mode, and therefore assume that the
> drive use CHS mode (physical addressing mode). The ATA spec tells large
> drives to return C/H/S = 16383/16/63 independent of their size, which in
> this case result in the IDE drive believe that the disk is only 8GB.
>
> I looked a little bit on the MIPS specific IDE code (in
> include/asm-mips/ide.h) and the way things are handled for bigendian
> systems.
> I have attached a patch below which should handle the IDE data
> correctly. I also believe it's more in sync with the other bigendian
> architectures.
> Now I can see the full size of my 30GB disk, it is hard to find a
> smaller disk these days :-)
>
> /Carsten
>
> Index: include/asm-mips/ide.h
> ===================================================================
> RCS file: /home/repository/sw/linux-2.4.0/include/asm-mips/ide.h,v
> retrieving revision 1.1.1.2
> diff -u -r1.1.1.2 ide.h
> --- include/asm-mips/ide.h      2001/02/26 09:18:02     1.1.1.2
> +++ include/asm-mips/ide.h      2001/04/20 09:57:59
> @@ -14,6 +14,7 @@
>  #ifdef __KERNEL__
>
>  #include <linux/config.h>
> +#include <asm/io.h>
>
>  #ifndef MAX_HWIFS
>  # ifdef CONFIG_BLK_DEV_IDEPCI
> @@ -89,13 +90,21 @@
>  typedef union {
>         unsigned all                    : 8;    /* all of the bits
> together */
>         struct {
> +#ifdef __MIPSEB__
> +               unsigned bit7           : 1;    /* always 1 */
> +               unsigned lba            : 1;    /* using LBA instead of
> CHS */
> +               unsigned bit5           : 1;    /* always 1 */
> +               unsigned unit           : 1;    /* drive select number,
> 0 or 1 */
> +               unsigned head           : 4;    /* always zeros here */
> +#else
>                 unsigned head           : 4;    /* always zeros here */
>                 unsigned unit           : 1;    /* drive select number,
> 0 or 1 */
>                 unsigned bit5           : 1;    /* always 1 */
>                 unsigned lba            : 1;    /* using LBA instead of
> CHS */
>                 unsigned bit7           : 1;    /* always 1 */
> +#endif
>         } b;
> -       } select_t;
> +} select_t;
>
>  static __inline__ int ide_request_irq(unsigned int irq, void
> (*handler)(int,void *, struct pt_regs *),
>                         unsigned long flags, const char *device, void
> *dev_id)
> @@ -125,57 +134,99 @@
>         ide_ops->ide_release_region(from, extent);
>  }
>
> +#undef  SUPPORT_SLOW_DATA_PORTS
> +#define SUPPORT_SLOW_DATA_PORTS 0
>
> -#if defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)
> +#undef  SUPPORT_VLB_SYNC
> +#define SUPPORT_VLB_SYNC 0
>
> -#ifdef insl
> -#undef insl
> -#endif
> -#ifdef outsl
> -#undef outsl
> -#endif
> -#ifdef insw
> -#undef insw
> -#endif
> -#ifdef outsw
> -#undef outsw
> -#endif
> +#if defined(__MIPSEB__)
>
> -#define insw(p,a,c)
> \
> -do {
> \
> -       unsigned short *ptr = (unsigned short *)(a);
> \
> -       unsigned int i = (c);
> \
> -       while (i--)
> \
> -               *ptr++ = inw(p);
> \
> -} while (0)
> -#define insl(p,a,c)
> \
> -do {
> \
> -       unsigned long *ptr = (unsigned long *)(a);
> \
> -       unsigned int i = (c);
> \
> -       while (i--)
> \
> -               *ptr++ = inl(p);
> \
> -} while (0)
> -#define outsw(p,a,c)
> \
> -do {
> \
> -       unsigned short *ptr = (unsigned short *)(a);
> \
> -       unsigned int i = (c);
> \
> -       while (i--)
> \
> -               outw(*ptr++, (p));
> \
> -} while (0)
> -#define outsl(p,a,c) {
> \
> -       unsigned long *ptr = (unsigned long *)(a);
> \
> -       unsigned int i = (c);
> \
> -       while (i--)
> \
> -               outl(*ptr++, (p));
> \
> -} while (0)
> +#define T_CHAR          (0x0000)        /* char:  don't touch  */
> +#define T_SHORT         (0x4000)        /* short: 12 -> 21     */
> +#define T_INT           (0x8000)        /* int:   1234 -> 4321 */
> +#define T_TEXT          (0xc000)        /* text:  12 -> 21     */
> +
> +#define T_MASK_TYPE     (0xc000)
> +#define T_MASK_COUNT    (0x3fff)
> +
> +#define D_CHAR(cnt)     (T_CHAR  | (cnt))
> +#define D_SHORT(cnt)    (T_SHORT | (cnt))
> +#define D_INT(cnt)      (T_INT   | (cnt))
> +#define D_TEXT(cnt)     (T_TEXT  | (cnt))
> +
> +static u_short driveid_types[] = {
> +       D_SHORT(10),    /* config - vendor2 */
> +       D_TEXT(20),     /* serial_no */
> +       D_SHORT(3),     /* buf_type - ecc_bytes */
> +       D_TEXT(48),     /* fw_rev - model */
> +       D_CHAR(2),      /* max_multsect - vendor3 */
> +       D_SHORT(1),     /* dword_io */
> +       D_CHAR(2),      /* vendor4 - capability */
> +       D_SHORT(1),     /* reserved50 */
> +       D_CHAR(4),      /* vendor5 - tDMA */
> +       D_SHORT(4),     /* field_valid - cur_sectors */
> +       D_INT(1),       /* cur_capacity */
> +       D_CHAR(2),      /* multsect - multsect_valid */
> +       D_INT(1),       /* lba_capacity */
> +       D_SHORT(194)    /* dma_1word - reservedyy */
> +};
>
> -#endif /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
> +#define num_driveid_types
> (sizeof(driveid_types)/sizeof(*driveid_types))
>
> +static __inline__ void ide_fix_driveid(struct hd_driveid *id)
> +{
> +       u_char *p = (u_char *)id;
> +       int i, j, cnt;
> +       u_char t;
> +
> +       for (i = 0; i < num_driveid_types; i++) {
> +               cnt = driveid_types[i] & T_MASK_COUNT;
> +               switch (driveid_types[i] & T_MASK_TYPE) {
> +               case T_CHAR:
> +                       p += cnt;
> +                       break;
> +               case T_SHORT:
> +                       for (j = 0; j < cnt; j++) {
> +                               t = p[0];
> +                               p[0] = p[1];
> +                               p[1] = t;
> +                               p += 2;
> +                       }
> +                       break;
> +               case T_INT:
> +                       for (j = 0; j < cnt; j++) {
> +                               t = p[0];
> +                               p[0] = p[3];
> +                               p[3] = t;
> +                               t = p[1];
> +                               p[1] = p[2];
> +                               p[2] = t;
> +                               p += 4;
> +                       }
> +                       break;
> +               case T_TEXT:
> +                       for (j = 0; j < cnt; j += 2) {
> +                               t = p[0];
> +                               p[0] = p[1];
> +                               p[1] = t;
> +                               p += 2;
> +                       }
> +                       break;
> +               };
> +       }
> +}
> +
> +#else /* defined(CONFIG_SWAP_IO_SPACE) && defined(__MIPSEB__)  */
> +
> +#define ide_fix_driveid(id)            do {} while (0)
> +
> +#endif
> +
>  /*
>   * The following are not needed for the non-m68k ports
>   */
>  #define ide_ack_intr(hwif)             (1)
> -#define ide_fix_driveid(id)            do {} while (0)
>  #define ide_release_lock(lock)         do {} while (0)
>  #define ide_get_lock(lock, hdlr, data) do {} while (0)
>
> --
> _    _ ____  ___   Carsten Langgaard  Mailto:carstenl@mips.com
> |\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
> | \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
>   TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
>                    Denmark            http://www.mips.com

--
_    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com




<Prev in Thread] Current Thread [Next in Thread>