diff options
author | ken <ken@FreeBSD.org> | 1998-09-18 22:33:59 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 1998-09-18 22:33:59 +0000 |
commit | b1e2d556fc3ac0cf8b7428eac3adb108a35d95c6 (patch) | |
tree | 8065269e4383504b33b65ff66ea37908426c3570 /sys/cam | |
parent | e00d4f6e8d46a42e518512b38e0d2fb3d89e7470 (diff) | |
download | FreeBSD-src-b1e2d556fc3ac0cf8b7428eac3adb108a35d95c6.zip FreeBSD-src-b1e2d556fc3ac0cf8b7428eac3adb108a35d95c6.tar.gz |
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
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/scsi/scsi_all.c | 143 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_all.h | 70 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 146 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.h | 72 |
4 files changed, 209 insertions, 222 deletions
diff --git a/sys/cam/scsi/scsi_all.c b/sys/cam/scsi/scsi_all.c index 129847f..4f892bd 100644 --- a/sys/cam/scsi/scsi_all.c +++ b/sys/cam/scsi/scsi_all.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id$ + * $Id: scsi_all.c,v 1.1 1998/09/15 06:36:33 gibbs Exp $ */ #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); } +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 * 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 : entry->media_type & SIP_MEDIA_FIXED) && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) - && (cam_strmatch(inq->product, entry->product, sizeof(inq->product)) == 0) - && (cam_strmatch(inq->revision, entry->revision, sizeof(inq->revision)) == 0)) { + && (cam_strmatch(inq->product, entry->product, + sizeof(inq->product)) == 0) + && (cam_strmatch(inq->revision, entry->revision, + sizeof(inq->revision)) == 0)) { return (0); } 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 : entry->media_type & SIP_MEDIA_FIXED) && (cam_strmatch(inq->vendor, entry->vendor, sizeof(inq->vendor)) == 0) - && (cam_strmatch(inq->product, entry->product, sizeof(inq->product)) == 0) - && (cam_strmatch(inq->revision, entry->revision, sizeof(inq->revision)) == 0)) { + && (cam_strmatch(inq->product, entry->product, + sizeof(inq->product)) == 0) + && (cam_strmatch(inq->revision, entry->revision, + sizeof(inq->revision)) == 0)) { return (0); } return (-1); diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index b8920f5..1af5a84 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -14,7 +14,7 @@ * * 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; }; +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_2 0x03 @@ -349,14 +397,19 @@ struct scsi_write_buffer #define TEST_UNIT_READY 0x00 #define REQUEST_SENSE 0x03 +#define READ_6 0x08 +#define WRITE_6 0x0a #define INQUIRY 0x12 #define MODE_SELECT_6 0x15 #define MODE_SENSE_6 0x1a +#define START_STOP_UNIT 0x1b #define START_STOP 0x1b #define RESERVE 0x16 #define RELEASE 0x17 #define PREVENT_ALLOW 0x1e #define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a #define POSITION_TO_ELEMENT 0x2b #define SYNCHRONIZE_CACHE 0x35 #define WRITE_BUFFER 0x3b @@ -365,6 +418,8 @@ struct scsi_write_buffer #define MODE_SELECT_10 0x55 #define MODE_SENSE_10 0x5A #define MOVE_MEDIUM 0xa5 +#define READ_12 0xa8 +#define WRITE_12 0xaa #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_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_static_inquiry_match(caddr_t inqbuffer, caddr_t table_entry); diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index b9b1742..d14ce30 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -25,15 +25,13 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * 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/queue.h> -#ifdef KERNEL #include <sys/systm.h> #include <sys/kernel.h> -#endif #include <sys/types.h> #include <sys/buf.h> #include <sys/devicestat.h> @@ -43,19 +41,12 @@ #include <sys/malloc.h> #include <sys/conf.h> -#ifdef KERNEL #include <machine/cons.h> /* For cncheckc */ #include <machine/md_var.h> /* For Maxmem */ #include <vm/vm.h> #include <vm/vm_prot.h> #include <vm/pmap.h> -#endif - -#ifndef KERNEL -#include <stdio.h> -#include <string.h> -#endif #include <cam/cam.h> #include <cam/cam_ccb.h> @@ -68,7 +59,6 @@ #include <cam/scsi/scsi_message.h> #include <cam/scsi/scsi_da.h> -#ifdef KERNEL typedef enum { DA_STATE_PROBE, @@ -1360,138 +1350,6 @@ dasetgeom(struct cam_periph *periph, struct scsi_read_capacity_data * rdcap) 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 dasendorderedtag(void *arg) { @@ -1516,5 +1374,3 @@ dasendorderedtag(void *arg) timeout(dasendorderedtag, NULL, (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL); } - -#endif /* KERNEL */ diff --git a/sys/cam/scsi/scsi_da.h b/sys/cam/scsi/scsi_da.h index 8cb1775..d9b95e3 100644 --- a/sys/cam/scsi/scsi_da.h +++ b/sys/cam/scsi/scsi_da.h @@ -46,7 +46,7 @@ * * 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 @@ -71,54 +71,6 @@ struct scsi_reassign_blocks 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 { u_int8_t opcode; @@ -177,16 +129,9 @@ struct scsi_read_defect_data_12 */ #define REZERO_UNIT 0x01 #define REASSIGN_BLOCKS 0x07 -#define READ_6 0x08 -#define WRITE_6 0x0a #define MODE_SELECT 0x15 #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_12 0xa8 -#define WRITE_12 0xaa #define READ_DEFECT_DATA_12 0xb7 @@ -373,19 +318,4 @@ struct scsi_da_rw_recovery_page { 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 */ |