Use READ/WRITE (16) if the LBA is larger than 32 bits. Another bit

of kern/28514.
This commit is contained in:
thorpej 2004-12-04 19:02:25 +00:00
parent b2618f9ac2
commit e0747e9825
3 changed files with 58 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsipi_disk.h,v 1.10 2004/12/03 20:20:32 thorpej Exp $ */
/* $NetBSD: scsipi_disk.h,v 1.11 2004/12/04 19:02:25 thorpej Exp $ */
/*
* SCSI and SCSI-like interfaces description
@ -61,15 +61,39 @@
struct scsipi_rw_big {
u_int8_t opcode;
u_int8_t byte2;
#define SRWB_RELADDR 0x01
#define SRWB_RELADDR 0x01 /* obsolete */
#define SRWB_FUA_NV 0x02 /* force unit access non-volatile cache */
#define SRWB_FUA 0x08 /* force unit access */
#define SRWB_DPO 0x10 /* disable page out */
#define SRWB_PROTECT(x) ((x) << 5)
u_int8_t addr[4];
u_int8_t reserved;
u_int8_t length[2];
u_int8_t control;
} __attribute__((packed));
#define READ_12 0xa8
#define WRITE_12 0xaa
struct scsipi_rw_12 {
u_int8_t opcode;
u_int8_t byte2; /* see scsipi_rw_big bits */
u_int8_t addr[4];
u_int8_t length[4];
u_int8_t byte11;
u_int8_t control;
};
#define READ_16 0x88
#define WRITE_16 0x8a
struct scsipi_rw_16 {
u_int8_t opcode;
u_int8_t byte2; /* see scsipi_rw_big bits */
u_int8_t addr[8];
u_int8_t length[4];
u_int8_t byte15;
u_int8_t control;
};
#define READ_CAPACITY 0x25
struct scsipi_read_capacity {
u_int8_t opcode;

View File

@ -1,4 +1,4 @@
/* $NetBSD: scsipiconf.h,v 1.91 2004/12/03 20:20:32 thorpej Exp $ */
/* $NetBSD: scsipiconf.h,v 1.92 2004/12/04 19:02:25 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2004 The NetBSD Foundation, Inc.
@ -727,6 +727,20 @@ _lto4b(u_int32_t val, u_int8_t *bytes)
bytes[3] = val & 0xff;
}
static __inline void __unused
_lto8b(u_int64_t val, u_int8_t *bytes)
{
bytes[0] = (val >> 56) & 0xff;
bytes[1] = (val >> 48) & 0xff;
bytes[2] = (val >> 40) & 0xff;
bytes[3] = (val >> 32) & 0xff;
bytes[4] = (val >> 24) & 0xff;
bytes[5] = (val >> 16) & 0xff;
bytes[6] = (val >> 8) & 0xff;
bytes[7] = val & 0xff;
}
static __inline u_int32_t __unused
_2btol(const u_int8_t *bytes)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: sd.c,v 1.229 2004/10/28 07:07:45 yamt Exp $ */
/* $NetBSD: sd.c,v 1.230 2004/12/04 19:02:26 thorpej Exp $ */
/*-
* Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@ -54,7 +54,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.229 2004/10/28 07:07:45 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.230 2004/12/04 19:02:26 thorpej Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@ -773,6 +773,7 @@ sdstart(struct scsipi_periph *periph)
struct sd_softc *sd = (void *)periph->periph_dev;
struct disklabel *lp = sd->sc_dk.dk_label;
struct buf *bp = 0;
struct scsipi_rw_16 cmd16;
struct scsipi_rw_big cmd_big;
struct scsi_rw cmd_small;
struct scsipi_generic *cmdp;
@ -829,15 +830,13 @@ sdstart(struct scsipi_periph *periph)
nblks = howmany(bp->b_bcount, lp->d_secsize);
/*
* Fill out the scsi command. If the transfer will
* fit in a "small" cdb, use it.
* Fill out the scsi command. Use the smallest CDB possible
* (6-byte, 10-byte, or 16-byte).
*/
if (((bp->b_rawblkno & 0x1fffff) == bp->b_rawblkno) &&
((nblks & 0xff) == nblks) &&
!(periph->periph_quirks & PQUIRK_ONLYBIG)) {
/*
* We can fit in a small cdb.
*/
/* 6-byte CDB */
memset(&cmd_small, 0, sizeof(cmd_small));
cmd_small.opcode = (bp->b_flags & B_READ) ?
SCSI_READ_COMMAND : SCSI_WRITE_COMMAND;
@ -845,10 +844,8 @@ sdstart(struct scsipi_periph *periph)
cmd_small.length = nblks & 0xff;
cmdlen = sizeof(cmd_small);
cmdp = (struct scsipi_generic *)&cmd_small;
} else {
/*
* Need a large cdb.
*/
} else if ((bp->b_rawblkno & 0xffffffff) == bp->b_rawblkno) {
/* 10-byte CDB */
memset(&cmd_big, 0, sizeof(cmd_big));
cmd_big.opcode = (bp->b_flags & B_READ) ?
READ_BIG : WRITE_BIG;
@ -856,6 +853,15 @@ sdstart(struct scsipi_periph *periph)
_lto2b(nblks, cmd_big.length);
cmdlen = sizeof(cmd_big);
cmdp = (struct scsipi_generic *)&cmd_big;
} else {
/* 16-byte CDB */
memset(&cmd16, 0, sizeof(cmd16));
cmd16.opcode = (bp->b_flags & B_READ) ?
READ_16 : WRITE_16;
_lto8b(bp->b_rawblkno, cmd16.addr);
_lto4b(nblks, cmd16.length);
cmdlen = sizeof(cmd16);
cmdp = (struct scsipi_generic *)&cmd16;
}
/* Instrumentation. */