SCSI >2TiB support.
* grub-core/disk/scsi.c (grub_scsi_read16): New function. (grub_scsi_write16): Likewise. (grub_scsi_read): Use read16 when necessary. (grub_scsi_write): Likewise. * include/grub/scsicmd.h (grub_scsi_read16): New struct. (grub_scsi_write16): Likewise. (grub_scsi_cmd_t): Add READ16 and WRITE16.
This commit is contained in:
parent
cc774926f1
commit
bc8d0f45a5
3 changed files with 111 additions and 3 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2012-01-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
SCSI >2TiB support.
|
||||||
|
|
||||||
|
* grub-core/disk/scsi.c (grub_scsi_read16): New function.
|
||||||
|
(grub_scsi_write16): Likewise.
|
||||||
|
(grub_scsi_read): Use read16 when necessary.
|
||||||
|
(grub_scsi_write): Likewise.
|
||||||
|
* include/grub/scsicmd.h (grub_scsi_read16): New struct.
|
||||||
|
(grub_scsi_write16): Likewise.
|
||||||
|
(grub_scsi_cmd_t): Add READ16 and WRITE16.
|
||||||
|
|
||||||
2012-01-30 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-01-30 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
SCSI write support (for usbms mainly).
|
SCSI write support (for usbms mainly).
|
||||||
|
|
|
@ -253,6 +253,38 @@ grub_scsi_read12 (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send a SCSI request for DISK: read SIZE sectors starting with
|
||||||
|
sector SECTOR to BUF. */
|
||||||
|
static grub_err_t
|
||||||
|
grub_scsi_read16 (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_size_t size, char *buf)
|
||||||
|
{
|
||||||
|
grub_scsi_t scsi;
|
||||||
|
struct grub_scsi_read16 rd;
|
||||||
|
grub_err_t err;
|
||||||
|
grub_err_t err_sense;
|
||||||
|
|
||||||
|
scsi = disk->data;
|
||||||
|
|
||||||
|
rd.opcode = grub_scsi_cmd_read16;
|
||||||
|
rd.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
|
||||||
|
rd.lba = grub_cpu_to_be64 (sector);
|
||||||
|
rd.size = grub_cpu_to_be32 (size);
|
||||||
|
rd.reserved = 0;
|
||||||
|
rd.control = 0;
|
||||||
|
|
||||||
|
err = scsi->dev->read (scsi, sizeof (rd), (char *) &rd, size * scsi->blocksize, buf);
|
||||||
|
|
||||||
|
/* Each SCSI command should be followed by Request Sense.
|
||||||
|
If not so, many devices STALLs or definitely freezes. */
|
||||||
|
err_sense = grub_scsi_request_sense (scsi);
|
||||||
|
if (err_sense != GRUB_ERR_NONE)
|
||||||
|
grub_errno = err;
|
||||||
|
/* err_sense is ignored for now and Request Sense Data also... */
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
|
/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
|
||||||
sectors starting with SECTOR. */
|
sectors starting with SECTOR. */
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
|
@ -321,6 +353,39 @@ grub_scsi_write12 (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Send a SCSI request for DISK: write the data stored in BUF to SIZE
|
||||||
|
sectors starting with SECTOR. */
|
||||||
|
static grub_err_t
|
||||||
|
grub_scsi_write16 (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
|
grub_size_t size, const char *buf)
|
||||||
|
{
|
||||||
|
grub_scsi_t scsi;
|
||||||
|
struct grub_scsi_write16 wr;
|
||||||
|
grub_err_t err;
|
||||||
|
grub_err_t err_sense;
|
||||||
|
|
||||||
|
scsi = disk->data;
|
||||||
|
|
||||||
|
wr.opcode = grub_scsi_cmd_write16;
|
||||||
|
wr.lun = scsi->lun << GRUB_SCSI_LUN_SHIFT;
|
||||||
|
wr.lba = grub_cpu_to_be64 (sector);
|
||||||
|
wr.size = grub_cpu_to_be32 (size);
|
||||||
|
wr.reserved = 0;
|
||||||
|
wr.control = 0;
|
||||||
|
|
||||||
|
err = scsi->dev->write (scsi, sizeof (wr), (char *) &wr, size * scsi->blocksize, buf);
|
||||||
|
|
||||||
|
/* Each SCSI command should be followed by Request Sense.
|
||||||
|
If not so, many devices STALLs or definitely freezes. */
|
||||||
|
err_sense = grub_scsi_request_sense (scsi);
|
||||||
|
if (err_sense != GRUB_ERR_NONE)
|
||||||
|
grub_errno = err;
|
||||||
|
/* err_sense is ignored for now and Request Sense Data also... */
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
grub_scsi_iterate (int (*hook) (const char *name),
|
grub_scsi_iterate (int (*hook) (const char *name),
|
||||||
|
@ -540,12 +605,18 @@ grub_scsi_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||||
switch (scsi->devtype)
|
switch (scsi->devtype)
|
||||||
{
|
{
|
||||||
case grub_scsi_devtype_direct:
|
case grub_scsi_devtype_direct:
|
||||||
|
if (sector >> 32)
|
||||||
|
err = grub_scsi_read16 (disk, sector, len, buf);
|
||||||
|
else
|
||||||
err = grub_scsi_read10 (disk, sector, len, buf);
|
err = grub_scsi_read10 (disk, sector, len, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case grub_scsi_devtype_cdrom:
|
case grub_scsi_devtype_cdrom:
|
||||||
|
if (sector >> 32)
|
||||||
|
err = grub_scsi_read16 (disk, sector, len, buf);
|
||||||
|
else
|
||||||
err = grub_scsi_read12 (disk, sector, len, buf);
|
err = grub_scsi_read12 (disk, sector, len, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -617,6 +688,9 @@ grub_scsi_write (grub_disk_t disk __attribute((unused)),
|
||||||
switch (scsi->devtype)
|
switch (scsi->devtype)
|
||||||
{
|
{
|
||||||
case grub_scsi_devtype_direct:
|
case grub_scsi_devtype_direct:
|
||||||
|
if (sector >> 32)
|
||||||
|
err = grub_scsi_write16 (disk, sector, len, buf);
|
||||||
|
else
|
||||||
err = grub_scsi_write10 (disk, sector, len, buf);
|
err = grub_scsi_write10 (disk, sector, len, buf);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -124,6 +124,16 @@ struct grub_scsi_read12
|
||||||
grub_uint8_t control;
|
grub_uint8_t control;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct grub_scsi_read16
|
||||||
|
{
|
||||||
|
grub_uint8_t opcode;
|
||||||
|
grub_uint8_t lun;
|
||||||
|
grub_uint64_t lba;
|
||||||
|
grub_uint32_t size;
|
||||||
|
grub_uint8_t reserved;
|
||||||
|
grub_uint8_t control;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct grub_scsi_write10
|
struct grub_scsi_write10
|
||||||
{
|
{
|
||||||
grub_uint8_t opcode;
|
grub_uint8_t opcode;
|
||||||
|
@ -145,6 +155,16 @@ struct grub_scsi_write12
|
||||||
grub_uint8_t control;
|
grub_uint8_t control;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct grub_scsi_write16
|
||||||
|
{
|
||||||
|
grub_uint8_t opcode;
|
||||||
|
grub_uint8_t lun;
|
||||||
|
grub_uint64_t lba;
|
||||||
|
grub_uint32_t size;
|
||||||
|
grub_uint8_t reserved;
|
||||||
|
grub_uint8_t control;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
grub_scsi_cmd_test_unit_ready = 0x00,
|
grub_scsi_cmd_test_unit_ready = 0x00,
|
||||||
|
@ -153,6 +173,8 @@ typedef enum
|
||||||
grub_scsi_cmd_read_capacity = 0x25,
|
grub_scsi_cmd_read_capacity = 0x25,
|
||||||
grub_scsi_cmd_read10 = 0x28,
|
grub_scsi_cmd_read10 = 0x28,
|
||||||
grub_scsi_cmd_write10 = 0x2a,
|
grub_scsi_cmd_write10 = 0x2a,
|
||||||
|
grub_scsi_cmd_read16 = 0x88,
|
||||||
|
grub_scsi_cmd_write16 = 0x8a,
|
||||||
grub_scsi_cmd_read12 = 0xa8,
|
grub_scsi_cmd_read12 = 0xa8,
|
||||||
grub_scsi_cmd_write12 = 0xaa,
|
grub_scsi_cmd_write12 = 0xaa,
|
||||||
} grub_scsi_cmd_t;
|
} grub_scsi_cmd_t;
|
||||||
|
|
Loading…
Reference in a new issue