mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Fix the CAM code so that people can compile kernels with the CD driver but
without the DA driver. The problem was that the CD driver depended on scsi_read_write() and scsi_start_stop(), which were defined in scsi_da.c. I moved both functions, and their associated data structures and defines from scsi_da.* to scsi_all.*. This is technically the "wrong" thing to do since those commands are really only for direct-access type devices, not for all SCSI devices. I think, though, that the advantage (allowing people to compile kernels without the disk driver) outweighs any architectural purity arguments. PR: kern/7969 Reviewed by: gibbs
This commit is contained in:
parent
71bf9f8a93
commit
37b9efd37b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=39466
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: scsi_all.c,v 1.1 1998/09/15 06:36:33 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -2627,6 +2627,135 @@ scsi_synchronize_cache(struct ccb_scsiio *csio, u_int32_t retries,
|
|||||||
scsi_ulto2b(lb_count, scsi_cmd->lb_count);
|
scsi_ulto2b(lb_count, scsi_cmd->lb_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
|
||||||
|
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||||
|
u_int8_t tag_action, int readop, u_int8_t byte2,
|
||||||
|
int minimum_cmd_size, u_int32_t lba, u_int32_t block_count,
|
||||||
|
u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
|
||||||
|
u_int32_t timeout)
|
||||||
|
{
|
||||||
|
u_int8_t cdb_len;
|
||||||
|
/*
|
||||||
|
* Use the smallest possible command to perform the operation
|
||||||
|
* as some legacy hardware does not support the 10 byte
|
||||||
|
* commands. If any of the lower 5 bits in byte2 is set, we have
|
||||||
|
* to go with a larger command.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
if ((minimum_cmd_size < 10)
|
||||||
|
&& ((lba & 0x1fffff) == lba)
|
||||||
|
&& ((block_count & 0xff) == block_count)
|
||||||
|
&& ((byte2 & 0xe0) == 0)) {
|
||||||
|
/*
|
||||||
|
* We can fit in a 6 byte cdb.
|
||||||
|
*/
|
||||||
|
struct scsi_rw_6 *scsi_cmd;
|
||||||
|
|
||||||
|
scsi_cmd = (struct scsi_rw_6 *)&csio->cdb_io.cdb_bytes;
|
||||||
|
scsi_cmd->opcode = readop ? READ_6 : WRITE_6;
|
||||||
|
scsi_ulto3b(lba, scsi_cmd->addr);
|
||||||
|
scsi_cmd->length = block_count & 0xff;
|
||||||
|
scsi_cmd->control = 0;
|
||||||
|
cdb_len = sizeof(*scsi_cmd);
|
||||||
|
|
||||||
|
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
||||||
|
("6byte: %x%x%x:%d:%d\n", scsi_cmd->addr[0],
|
||||||
|
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
||||||
|
scsi_cmd->length, dxfer_len));
|
||||||
|
} else if ((minimum_cmd_size < 12)
|
||||||
|
&& ((block_count & 0xffff) == block_count)) {
|
||||||
|
/*
|
||||||
|
* Need a 10 byte cdb.
|
||||||
|
*/
|
||||||
|
struct scsi_rw_10 *scsi_cmd;
|
||||||
|
|
||||||
|
scsi_cmd = (struct scsi_rw_10 *)&csio->cdb_io.cdb_bytes;
|
||||||
|
scsi_cmd->opcode = readop ? READ_10 : WRITE_10;
|
||||||
|
scsi_cmd->byte2 = byte2;
|
||||||
|
scsi_ulto4b(lba, scsi_cmd->addr);
|
||||||
|
scsi_cmd->reserved = 0;
|
||||||
|
scsi_ulto2b(block_count, scsi_cmd->length);
|
||||||
|
scsi_cmd->control = 0;
|
||||||
|
cdb_len = sizeof(*scsi_cmd);
|
||||||
|
|
||||||
|
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
||||||
|
("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0],
|
||||||
|
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
||||||
|
scsi_cmd->addr[3], scsi_cmd->length[0],
|
||||||
|
scsi_cmd->length[1], dxfer_len));
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The block count is too big for a 10 byte CDB, use a 12
|
||||||
|
* byte CDB. READ/WRITE(12) are currently only defined for
|
||||||
|
* optical devices.
|
||||||
|
*/
|
||||||
|
struct scsi_rw_12 *scsi_cmd;
|
||||||
|
|
||||||
|
scsi_cmd = (struct scsi_rw_12 *)&csio->cdb_io.cdb_bytes;
|
||||||
|
scsi_cmd->opcode = readop ? READ_12 : WRITE_12;
|
||||||
|
scsi_cmd->byte2 = byte2;
|
||||||
|
scsi_ulto4b(lba, scsi_cmd->addr);
|
||||||
|
scsi_cmd->reserved = 0;
|
||||||
|
scsi_ulto4b(block_count, scsi_cmd->length);
|
||||||
|
scsi_cmd->control = 0;
|
||||||
|
cdb_len = sizeof(*scsi_cmd);
|
||||||
|
|
||||||
|
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
||||||
|
("12byte: %x%x%x%x:%x%x%x%x: %d\n", scsi_cmd->addr[0],
|
||||||
|
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
||||||
|
scsi_cmd->addr[3], scsi_cmd->length[0],
|
||||||
|
scsi_cmd->length[1], scsi_cmd->length[2],
|
||||||
|
scsi_cmd->length[3], dxfer_len));
|
||||||
|
}
|
||||||
|
cam_fill_csio(csio,
|
||||||
|
retries,
|
||||||
|
cbfcnp,
|
||||||
|
/*flags*/readop ? CAM_DIR_IN : CAM_DIR_OUT,
|
||||||
|
tag_action,
|
||||||
|
data_ptr,
|
||||||
|
dxfer_len,
|
||||||
|
sense_len,
|
||||||
|
cdb_len,
|
||||||
|
timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
|
||||||
|
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||||
|
u_int8_t tag_action, int start, int load_eject,
|
||||||
|
int immediate, u_int8_t sense_len, u_int32_t timeout)
|
||||||
|
{
|
||||||
|
struct scsi_start_stop_unit *scsi_cmd;
|
||||||
|
int extra_flags = 0;
|
||||||
|
|
||||||
|
scsi_cmd = (struct scsi_start_stop_unit *)&csio->cdb_io.cdb_bytes;
|
||||||
|
bzero(scsi_cmd, sizeof(*scsi_cmd));
|
||||||
|
scsi_cmd->opcode = START_STOP_UNIT;
|
||||||
|
if (start != 0) {
|
||||||
|
scsi_cmd->how |= SSS_START;
|
||||||
|
/* it takes a lot of power to start a drive */
|
||||||
|
extra_flags |= CAM_HIGH_POWER;
|
||||||
|
}
|
||||||
|
if (load_eject != 0)
|
||||||
|
scsi_cmd->how |= SSS_LOEJ;
|
||||||
|
if (immediate != 0)
|
||||||
|
scsi_cmd->byte2 |= SSS_IMMED;
|
||||||
|
|
||||||
|
cam_fill_csio(csio,
|
||||||
|
retries,
|
||||||
|
cbfcnp,
|
||||||
|
/*flags*/CAM_DIR_NONE | extra_flags,
|
||||||
|
tag_action,
|
||||||
|
/*data_ptr*/NULL,
|
||||||
|
/*dxfer_len*/0,
|
||||||
|
sense_len,
|
||||||
|
sizeof(*scsi_cmd),
|
||||||
|
timeout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try make as good a match as possible with
|
* Try make as good a match as possible with
|
||||||
* available sub drivers
|
* available sub drivers
|
||||||
@ -2645,8 +2774,10 @@ scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry)
|
|||||||
&& (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE
|
&& (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE
|
||||||
: entry->media_type & SIP_MEDIA_FIXED)
|
: entry->media_type & SIP_MEDIA_FIXED)
|
||||||
&& (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0)
|
&& (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0)
|
||||||
&& (cam_strmatch(inq->product, entry->product, sizeof(inq->product)) == 0)
|
&& (cam_strmatch(inq->product, entry->product,
|
||||||
&& (cam_strmatch(inq->revision, entry->revision, sizeof(inq->revision)) == 0)) {
|
sizeof(inq->product)) == 0)
|
||||||
|
&& (cam_strmatch(inq->revision, entry->revision,
|
||||||
|
sizeof(inq->revision)) == 0)) {
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -2670,8 +2801,10 @@ scsi_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry)
|
|||||||
&& (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE
|
&& (SID_IS_REMOVABLE(inq) ? entry->media_type & SIP_MEDIA_REMOVABLE
|
||||||
: entry->media_type & SIP_MEDIA_FIXED)
|
: entry->media_type & SIP_MEDIA_FIXED)
|
||||||
&& (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0)
|
&& (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0)
|
||||||
&& (cam_strmatch(inq->product, entry->product, sizeof(inq->product)) == 0)
|
&& (cam_strmatch(inq->product, entry->product,
|
||||||
&& (cam_strmatch(inq->revision, entry->revision, sizeof(inq->revision)) == 0)) {
|
sizeof(inq->product)) == 0)
|
||||||
|
&& (cam_strmatch(inq->revision, entry->revision,
|
||||||
|
sizeof(inq->revision)) == 0)) {
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||||
*
|
*
|
||||||
* $Id: scsi_all.h,v 1.13 1995/05/30 08:13:25 rgrimes Exp $
|
* $Id: scsi_all.h,v 1.1 1998/09/15 06:36:34 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -340,6 +340,54 @@ struct scsi_write_buffer
|
|||||||
u_int8_t control;
|
u_int8_t control;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct scsi_rw_6
|
||||||
|
{
|
||||||
|
u_int8_t opcode;
|
||||||
|
u_int8_t addr[3];
|
||||||
|
/* only 5 bits are valid in the MSB address byte */
|
||||||
|
#define SRW_TOPADDR 0x1F
|
||||||
|
u_int8_t length;
|
||||||
|
u_int8_t control;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scsi_rw_10
|
||||||
|
{
|
||||||
|
u_int8_t opcode;
|
||||||
|
#define SRW10_RELADDR 0x01
|
||||||
|
#define SRW10_FUA 0x08
|
||||||
|
#define SRW10_DPO 0x10
|
||||||
|
u_int8_t byte2;
|
||||||
|
u_int8_t addr[4];
|
||||||
|
u_int8_t reserved;
|
||||||
|
u_int8_t length[2];
|
||||||
|
u_int8_t control;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scsi_rw_12
|
||||||
|
{
|
||||||
|
u_int8_t opcode;
|
||||||
|
#define SRW12_RELADDR 0x01
|
||||||
|
#define SRW12_FUA 0x08
|
||||||
|
#define SRW12_DPO 0x10
|
||||||
|
u_int8_t byte2;
|
||||||
|
u_int8_t addr[4];
|
||||||
|
u_int8_t reserved;
|
||||||
|
u_int8_t length[4];
|
||||||
|
u_int8_t control;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scsi_start_stop_unit
|
||||||
|
{
|
||||||
|
u_int8_t opcode;
|
||||||
|
u_int8_t byte2;
|
||||||
|
#define SSS_IMMED 0x01
|
||||||
|
u_int8_t reserved[2];
|
||||||
|
u_int8_t how;
|
||||||
|
#define SSS_START 0x01
|
||||||
|
#define SSS_LOEJ 0x02
|
||||||
|
u_int8_t control;
|
||||||
|
};
|
||||||
|
|
||||||
#define SC_SCSI_1 0x01
|
#define SC_SCSI_1 0x01
|
||||||
#define SC_SCSI_2 0x03
|
#define SC_SCSI_2 0x03
|
||||||
|
|
||||||
@ -349,14 +397,19 @@ struct scsi_write_buffer
|
|||||||
|
|
||||||
#define TEST_UNIT_READY 0x00
|
#define TEST_UNIT_READY 0x00
|
||||||
#define REQUEST_SENSE 0x03
|
#define REQUEST_SENSE 0x03
|
||||||
|
#define READ_6 0x08
|
||||||
|
#define WRITE_6 0x0a
|
||||||
#define INQUIRY 0x12
|
#define INQUIRY 0x12
|
||||||
#define MODE_SELECT_6 0x15
|
#define MODE_SELECT_6 0x15
|
||||||
#define MODE_SENSE_6 0x1a
|
#define MODE_SENSE_6 0x1a
|
||||||
|
#define START_STOP_UNIT 0x1b
|
||||||
#define START_STOP 0x1b
|
#define START_STOP 0x1b
|
||||||
#define RESERVE 0x16
|
#define RESERVE 0x16
|
||||||
#define RELEASE 0x17
|
#define RELEASE 0x17
|
||||||
#define PREVENT_ALLOW 0x1e
|
#define PREVENT_ALLOW 0x1e
|
||||||
#define READ_CAPACITY 0x25
|
#define READ_CAPACITY 0x25
|
||||||
|
#define READ_10 0x28
|
||||||
|
#define WRITE_10 0x2a
|
||||||
#define POSITION_TO_ELEMENT 0x2b
|
#define POSITION_TO_ELEMENT 0x2b
|
||||||
#define SYNCHRONIZE_CACHE 0x35
|
#define SYNCHRONIZE_CACHE 0x35
|
||||||
#define WRITE_BUFFER 0x3b
|
#define WRITE_BUFFER 0x3b
|
||||||
@ -365,6 +418,8 @@ struct scsi_write_buffer
|
|||||||
#define MODE_SELECT_10 0x55
|
#define MODE_SELECT_10 0x55
|
||||||
#define MODE_SENSE_10 0x5A
|
#define MODE_SENSE_10 0x5A
|
||||||
#define MOVE_MEDIUM 0xa5
|
#define MOVE_MEDIUM 0xa5
|
||||||
|
#define READ_12 0xa8
|
||||||
|
#define WRITE_12 0xaa
|
||||||
#define READ_ELEMENT_STATUS 0xb8
|
#define READ_ELEMENT_STATUS 0xb8
|
||||||
|
|
||||||
|
|
||||||
@ -713,6 +768,19 @@ void scsi_synchronize_cache(struct ccb_scsiio *csio,
|
|||||||
u_int32_t begin_lba, u_int16_t lb_count,
|
u_int32_t begin_lba, u_int16_t lb_count,
|
||||||
u_int8_t sense_len, u_int32_t timeout);
|
u_int8_t sense_len, u_int32_t timeout);
|
||||||
|
|
||||||
|
void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
|
||||||
|
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||||
|
u_int8_t tag_action, int readop, u_int8_t byte2,
|
||||||
|
int minimum_cmd_size, u_int32_t lba,
|
||||||
|
u_int32_t block_count, u_int8_t *data_ptr,
|
||||||
|
u_int32_t dxfer_len, u_int8_t sense_len,
|
||||||
|
u_int32_t timeout);
|
||||||
|
|
||||||
|
void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
|
||||||
|
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
||||||
|
u_int8_t tag_action, int start, int load_eject,
|
||||||
|
int immediate, u_int8_t sense_len, u_int32_t timeout);
|
||||||
|
|
||||||
int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
|
int scsi_inquiry_match(caddr_t inqbuffer, caddr_t table_entry);
|
||||||
int scsi_static_inquiry_match(caddr_t inqbuffer,
|
int scsi_static_inquiry_match(caddr_t inqbuffer,
|
||||||
caddr_t table_entry);
|
caddr_t table_entry);
|
||||||
|
@ -25,15 +25,13 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: scsi_da.c,v 1.1 1998/09/15 06:36:34 gibbs Exp $
|
* $Id: scsi_da.c,v 1.2 1998/09/16 23:30:11 ken Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
#ifdef KERNEL
|
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/kernel.h>
|
#include <sys/kernel.h>
|
||||||
#endif
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/buf.h>
|
#include <sys/buf.h>
|
||||||
#include <sys/devicestat.h>
|
#include <sys/devicestat.h>
|
||||||
@ -43,19 +41,12 @@
|
|||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/conf.h>
|
#include <sys/conf.h>
|
||||||
|
|
||||||
#ifdef KERNEL
|
|
||||||
#include <machine/cons.h> /* For cncheckc */
|
#include <machine/cons.h> /* For cncheckc */
|
||||||
#include <machine/md_var.h> /* For Maxmem */
|
#include <machine/md_var.h> /* For Maxmem */
|
||||||
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/vm_prot.h>
|
#include <vm/vm_prot.h>
|
||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef KERNEL
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cam/cam.h>
|
#include <cam/cam.h>
|
||||||
#include <cam/cam_ccb.h>
|
#include <cam/cam_ccb.h>
|
||||||
@ -68,7 +59,6 @@
|
|||||||
#include <cam/scsi/scsi_message.h>
|
#include <cam/scsi/scsi_message.h>
|
||||||
#include <cam/scsi/scsi_da.h>
|
#include <cam/scsi/scsi_da.h>
|
||||||
|
|
||||||
#ifdef KERNEL
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DA_STATE_PROBE,
|
DA_STATE_PROBE,
|
||||||
@ -1360,138 +1350,6 @@ dasetgeom(struct cam_periph *periph, struct scsi_read_capacity_data * rdcap)
|
|||||||
dp->cylinders = ccg.cylinders;
|
dp->cylinders = ccg.cylinders;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* KERNEL */
|
|
||||||
|
|
||||||
void
|
|
||||||
scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
|
|
||||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
|
||||||
u_int8_t tag_action, int readop, u_int8_t byte2,
|
|
||||||
int minimum_cmd_size, u_int32_t lba, u_int32_t block_count,
|
|
||||||
u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len,
|
|
||||||
u_int32_t timeout)
|
|
||||||
{
|
|
||||||
u_int8_t cdb_len;
|
|
||||||
/*
|
|
||||||
* Use the smallest possible command to perform the operation
|
|
||||||
* as some legacy hardware does not support the 10 byte
|
|
||||||
* commands. If any of the lower 5 bits in byte2 is set, we have
|
|
||||||
* to go with a larger command.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if ((minimum_cmd_size < 10)
|
|
||||||
&& ((lba & 0x1fffff) == lba)
|
|
||||||
&& ((block_count & 0xff) == block_count)
|
|
||||||
&& ((byte2 & 0xe0) == 0)) {
|
|
||||||
/*
|
|
||||||
* We can fit in a 6 byte cdb.
|
|
||||||
*/
|
|
||||||
struct scsi_rw_6 *scsi_cmd;
|
|
||||||
|
|
||||||
scsi_cmd = (struct scsi_rw_6 *)&csio->cdb_io.cdb_bytes;
|
|
||||||
scsi_cmd->opcode = readop ? READ_6 : WRITE_6;
|
|
||||||
scsi_ulto3b(lba, scsi_cmd->addr);
|
|
||||||
scsi_cmd->length = block_count & 0xff;
|
|
||||||
scsi_cmd->control = 0;
|
|
||||||
cdb_len = sizeof(*scsi_cmd);
|
|
||||||
|
|
||||||
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
|
||||||
("6byte: %x%x%x:%d:%d\n", scsi_cmd->addr[0],
|
|
||||||
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
|
||||||
scsi_cmd->length, dxfer_len));
|
|
||||||
} else if ((minimum_cmd_size < 12)
|
|
||||||
&& ((block_count & 0xffff) == block_count)) {
|
|
||||||
/*
|
|
||||||
* Need a 10 byte cdb.
|
|
||||||
*/
|
|
||||||
struct scsi_rw_10 *scsi_cmd;
|
|
||||||
|
|
||||||
scsi_cmd = (struct scsi_rw_10 *)&csio->cdb_io.cdb_bytes;
|
|
||||||
scsi_cmd->opcode = readop ? READ_10 : WRITE_10;
|
|
||||||
scsi_cmd->byte2 = byte2;
|
|
||||||
scsi_ulto4b(lba, scsi_cmd->addr);
|
|
||||||
scsi_cmd->reserved = 0;
|
|
||||||
scsi_ulto2b(block_count, scsi_cmd->length);
|
|
||||||
scsi_cmd->control = 0;
|
|
||||||
cdb_len = sizeof(*scsi_cmd);
|
|
||||||
|
|
||||||
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
|
||||||
("10byte: %x%x%x%x:%x%x: %d\n", scsi_cmd->addr[0],
|
|
||||||
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
|
||||||
scsi_cmd->addr[3], scsi_cmd->length[0],
|
|
||||||
scsi_cmd->length[1], dxfer_len));
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* The block count is too big for a 10 byte CDB, use a 12
|
|
||||||
* byte CDB. READ/WRITE(12) are currently only defined for
|
|
||||||
* optical devices.
|
|
||||||
*/
|
|
||||||
struct scsi_rw_12 *scsi_cmd;
|
|
||||||
|
|
||||||
scsi_cmd = (struct scsi_rw_12 *)&csio->cdb_io.cdb_bytes;
|
|
||||||
scsi_cmd->opcode = readop ? READ_12 : WRITE_12;
|
|
||||||
scsi_cmd->byte2 = byte2;
|
|
||||||
scsi_ulto4b(lba, scsi_cmd->addr);
|
|
||||||
scsi_cmd->reserved = 0;
|
|
||||||
scsi_ulto4b(block_count, scsi_cmd->length);
|
|
||||||
scsi_cmd->control = 0;
|
|
||||||
cdb_len = sizeof(*scsi_cmd);
|
|
||||||
|
|
||||||
CAM_DEBUG(csio->ccb_h.path, CAM_DEBUG_SUBTRACE,
|
|
||||||
("12byte: %x%x%x%x:%x%x%x%x: %d\n", scsi_cmd->addr[0],
|
|
||||||
scsi_cmd->addr[1], scsi_cmd->addr[2],
|
|
||||||
scsi_cmd->addr[3], scsi_cmd->length[0],
|
|
||||||
scsi_cmd->length[1], scsi_cmd->length[2],
|
|
||||||
scsi_cmd->length[3], dxfer_len));
|
|
||||||
}
|
|
||||||
cam_fill_csio(csio,
|
|
||||||
retries,
|
|
||||||
cbfcnp,
|
|
||||||
/*flags*/readop ? CAM_DIR_IN : CAM_DIR_OUT,
|
|
||||||
tag_action,
|
|
||||||
data_ptr,
|
|
||||||
dxfer_len,
|
|
||||||
sense_len,
|
|
||||||
cdb_len,
|
|
||||||
timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
|
|
||||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
|
||||||
u_int8_t tag_action, int start, int load_eject,
|
|
||||||
int immediate, u_int8_t sense_len, u_int32_t timeout)
|
|
||||||
{
|
|
||||||
struct scsi_start_stop_unit *scsi_cmd;
|
|
||||||
int extra_flags = 0;
|
|
||||||
|
|
||||||
scsi_cmd = (struct scsi_start_stop_unit *)&csio->cdb_io.cdb_bytes;
|
|
||||||
bzero(scsi_cmd, sizeof(*scsi_cmd));
|
|
||||||
scsi_cmd->opcode = START_STOP_UNIT;
|
|
||||||
if (start != 0) {
|
|
||||||
scsi_cmd->how |= SSS_START;
|
|
||||||
/* it takes a lot of power to start a drive */
|
|
||||||
extra_flags |= CAM_HIGH_POWER;
|
|
||||||
}
|
|
||||||
if (load_eject != 0)
|
|
||||||
scsi_cmd->how |= SSS_LOEJ;
|
|
||||||
if (immediate != 0)
|
|
||||||
scsi_cmd->byte2 |= SSS_IMMED;
|
|
||||||
|
|
||||||
cam_fill_csio(csio,
|
|
||||||
retries,
|
|
||||||
cbfcnp,
|
|
||||||
/*flags*/CAM_DIR_NONE | extra_flags,
|
|
||||||
tag_action,
|
|
||||||
/*data_ptr*/NULL,
|
|
||||||
/*dxfer_len*/0,
|
|
||||||
sense_len,
|
|
||||||
sizeof(*scsi_cmd),
|
|
||||||
timeout);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef KERNEL
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dasendorderedtag(void *arg)
|
dasendorderedtag(void *arg)
|
||||||
{
|
{
|
||||||
@ -1516,5 +1374,3 @@ dasendorderedtag(void *arg)
|
|||||||
timeout(dasendorderedtag, NULL,
|
timeout(dasendorderedtag, NULL,
|
||||||
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
|
(DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* KERNEL */
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
*
|
*
|
||||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||||
*
|
*
|
||||||
* $Id$
|
* $Id: scsi_da.h,v 1.1 1998/09/15 06:36:34 gibbs Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SCSI_SCSI_DA_H
|
#ifndef _SCSI_SCSI_DA_H
|
||||||
@ -71,54 +71,6 @@ struct scsi_reassign_blocks
|
|||||||
u_int8_t control;
|
u_int8_t control;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct scsi_rw_6
|
|
||||||
{
|
|
||||||
u_int8_t opcode;
|
|
||||||
u_int8_t addr[3];
|
|
||||||
/* only 5 bits are valid in the MSB address byte */
|
|
||||||
#define SRW_TOPADDR 0x1F
|
|
||||||
u_int8_t length;
|
|
||||||
u_int8_t control;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct scsi_rw_10
|
|
||||||
{
|
|
||||||
u_int8_t opcode;
|
|
||||||
#define SRW10_RELADDR 0x01
|
|
||||||
#define SRW10_FUA 0x08
|
|
||||||
#define SRW10_DPO 0x10
|
|
||||||
u_int8_t byte2;
|
|
||||||
u_int8_t addr[4];
|
|
||||||
u_int8_t reserved;
|
|
||||||
u_int8_t length[2];
|
|
||||||
u_int8_t control;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct scsi_rw_12
|
|
||||||
{
|
|
||||||
u_int8_t opcode;
|
|
||||||
#define SRW12_RELADDR 0x01
|
|
||||||
#define SRW12_FUA 0x08
|
|
||||||
#define SRW12_DPO 0x10
|
|
||||||
u_int8_t byte2;
|
|
||||||
u_int8_t addr[4];
|
|
||||||
u_int8_t reserved;
|
|
||||||
u_int8_t length[4];
|
|
||||||
u_int8_t control;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct scsi_start_stop_unit
|
|
||||||
{
|
|
||||||
u_int8_t opcode;
|
|
||||||
u_int8_t byte2;
|
|
||||||
#define SSS_IMMED 0x01
|
|
||||||
u_int8_t reserved[2];
|
|
||||||
u_int8_t how;
|
|
||||||
#define SSS_START 0x01
|
|
||||||
#define SSS_LOEJ 0x02
|
|
||||||
u_int8_t control;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct scsi_read_defect_data_10
|
struct scsi_read_defect_data_10
|
||||||
{
|
{
|
||||||
u_int8_t opcode;
|
u_int8_t opcode;
|
||||||
@ -177,16 +129,9 @@ struct scsi_read_defect_data_12
|
|||||||
*/
|
*/
|
||||||
#define REZERO_UNIT 0x01
|
#define REZERO_UNIT 0x01
|
||||||
#define REASSIGN_BLOCKS 0x07
|
#define REASSIGN_BLOCKS 0x07
|
||||||
#define READ_6 0x08
|
|
||||||
#define WRITE_6 0x0a
|
|
||||||
#define MODE_SELECT 0x15
|
#define MODE_SELECT 0x15
|
||||||
#define MODE_SENSE 0x1a
|
#define MODE_SENSE 0x1a
|
||||||
#define START_STOP_UNIT 0x1b
|
|
||||||
#define READ_10 0x28
|
|
||||||
#define WRITE_10 0x2a
|
|
||||||
#define READ_DEFECT_DATA_10 0x37
|
#define READ_DEFECT_DATA_10 0x37
|
||||||
#define READ_12 0xa8
|
|
||||||
#define WRITE_12 0xaa
|
|
||||||
#define READ_DEFECT_DATA_12 0xb7
|
#define READ_DEFECT_DATA_12 0xb7
|
||||||
|
|
||||||
|
|
||||||
@ -373,19 +318,4 @@ struct scsi_da_rw_recovery_page {
|
|||||||
u_int8_t recovery_time_limit[2];
|
u_int8_t recovery_time_limit[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
void scsi_read_write(struct ccb_scsiio *csio, u_int32_t retries,
|
|
||||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
|
||||||
u_int8_t tag_action, int readop, u_int8_t byte2,
|
|
||||||
int minimum_cmd_size, u_int32_t lba,
|
|
||||||
u_int32_t block_count, u_int8_t *data_ptr,
|
|
||||||
u_int32_t dxfer_len, u_int8_t sense_len,
|
|
||||||
u_int32_t timeout);
|
|
||||||
|
|
||||||
void scsi_start_stop(struct ccb_scsiio *csio, u_int32_t retries,
|
|
||||||
void (*cbfcnp)(struct cam_periph *, union ccb *),
|
|
||||||
u_int8_t tag_action, int start, int load_eject,
|
|
||||||
int immediate, u_int8_t sense_len, u_int32_t timeout);
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif /* _SCSI_SCSI_DA_H */
|
#endif /* _SCSI_SCSI_DA_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user