Use READ/WRITE (16) if the LBA is larger than 32 bits. Another bit
of kern/28514.
This commit is contained in:
parent
b2618f9ac2
commit
e0747e9825
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue