diff options
Diffstat (limited to 'scsi/scsi_disk.c')
-rw-r--r-- | scsi/scsi_disk.c | 624 |
1 files changed, 0 insertions, 624 deletions
diff --git a/scsi/scsi_disk.c b/scsi/scsi_disk.c deleted file mode 100644 index 99bbe76..0000000 --- a/scsi/scsi_disk.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * File: scsi_disk.c - * Author: Alessandro Forin, Carnegie Mellon University - * Date: 10/90 - * - * Middle layer of the SCSI driver: SCSI protocol implementation - * - * This file contains code for SCSI commands for DISK devices. - */ - -#include <string.h> - -#include <mach/std_types.h> -#include <scsi/compat_30.h> - -#include <scsi/scsi.h> -#include <scsi/scsi2.h> -#include <scsi/scsi_defs.h> - -#if (NSCSI > 0) - - -char *scdisk_name(internal) - boolean_t internal; -{ - return internal ? "rz" : "disk"; -} - -/* - * SCSI commands partially specific to disks - */ -void scdisk_read( tgt, secno, ior) - register target_info_t *tgt; - register unsigned int secno; - io_req_t ior; -{ - scsi_cmd_read_t *cmd; - register unsigned len; - unsigned int max_dma_data; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - if (len < tgt->block_size) - len = tgt->block_size; - - cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_READ; - cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK; - cmd->scsi_cmd_lba2 = (secno>> 8)&0xff; - cmd->scsi_cmd_lba3 = (secno )&0xff; - cmd->scsi_cmd_xfer_len = len / tgt->block_size; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_READ; - - scsi_go(tgt, sizeof(*cmd), len, FALSE); -} - -void scdisk_write( tgt, secno, ior) - register target_info_t *tgt; - register unsigned int secno; - io_req_t ior; -{ - scsi_cmd_write_t *cmd; - unsigned len; /* in bytes */ - unsigned int max_dma_data; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - if (len < tgt->block_size) - len = tgt->block_size; - - cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_WRITE; - cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK; - cmd->scsi_cmd_lba2 = (secno>> 8)&0xff; - cmd->scsi_cmd_lba3 = (secno )&0xff; - cmd->scsi_cmd_xfer_len = len / tgt->block_size; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_WRITE; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - - -int scdisk_mode_select(tgt, lbn, ior, mdata, mlen, save) - register target_info_t *tgt; - register int lbn; - io_req_t ior; - char *mdata; - int mlen, save; -{ - scsi_cmd_mode_select_t *cmd; - scsi_mode_select_param_t *parm; - - bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm)); - cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT; - cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF; /* XXX only if... */ - cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t);/* no vuq */ - - parm = (scsi_mode_select_param_t*) (cmd + 1); - if (mdata) { - cmd->scsi_cmd_xfer_len = mlen; - bcopy(mdata, (char*)parm, mlen); - if (save) - cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_MSL_SP; - } else { - /* parm->medium_type = if (floppy)disk.. */ - parm->desc_len = 8; - /* this really is the LBN */ - parm->descs[0].density_code = 0;/* XXX default XXX */ - parm->descs[0].reclen1 = (lbn>>16)&0xff; - parm->descs[0].reclen2 = (lbn>> 8)&0xff; - parm->descs[0].reclen3 = (lbn )&0xff; - mlen = sizeof(*parm); - } - - tgt->cur_cmd = SCSI_CMD_MODE_SELECT; - - scsi_go_and_wait(tgt, sizeof(*cmd) + mlen, 0, ior); - - return tgt->done; -} - -/* - * SCSI commands fully specific to disks - */ -int scsi_read_capacity( tgt, lbn, ior) - register target_info_t *tgt; - int lbn; - io_req_t ior; -{ - scsi_cmd_read_capacity_t *cmd; - - bzero(tgt->cmd_ptr, sizeof(*cmd)); - cmd = (scsi_cmd_read_capacity_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_READ_CAPACITY; - /* all zeroes, unless... */ - if (lbn) { - cmd->scsi_cmd_rcap_flags = SCSI_CMD_RCAP_PMI; - cmd->scsi_cmd_lba1 = (lbn>>24); - cmd->scsi_cmd_lba2 = (lbn>>16)&0xff; - cmd->scsi_cmd_lba3 = (lbn>> 8)&0xff; - cmd->scsi_cmd_lba4 = (lbn )&0xff; - } - - tgt->cur_cmd = SCSI_CMD_READ_CAPACITY; - - scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_rcap_data_t),ior); - - return tgt->done; -} - -void scsi_reassign_blocks( tgt, defect_list, n_defects, ior) - register target_info_t *tgt; - unsigned int *defect_list; /* In ascending order ! */ - int n_defects; - io_req_t ior; -{ - scsi_cmd_reassign_blocks_t *cmd; - scsi_Ldefect_data_t *parm; - - cmd = (scsi_cmd_reassign_blocks_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_REASSIGN_BLOCKS; - cmd->scsi_cmd_lun_and_lba1 = 0; - cmd->scsi_cmd_lba2 = 0; - cmd->scsi_cmd_lba3 = 0; - cmd->scsi_cmd_xfer_len = 0; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - parm = (scsi_Ldefect_data_t *) (cmd + 1); - parm->res1 = parm->res2 = 0; - n_defects *= 4; /* in 4-byte-ints */ - parm->list_len_msb = n_defects >> 8; - parm->list_len_lsb = n_defects; - bcopy((char*)defect_list, (char*)parm->defects, n_defects); - - tgt->cur_cmd = SCSI_CMD_REASSIGN_BLOCKS; - - scsi_go(tgt, sizeof(*cmd) + sizeof(*parm) + (n_defects - 4), 0, FALSE); -} - -void scsi_medium_removal( tgt, allow, ior) - register target_info_t *tgt; - boolean_t allow; - io_req_t ior; -{ - scsi_cmd_medium_removal_t *cmd; - - cmd = (scsi_cmd_medium_removal_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_PREVENT_ALLOW_REMOVAL; - cmd->scsi_cmd_lun_and_lba1 = 0; - cmd->scsi_cmd_lba2 = 0; - cmd->scsi_cmd_lba3 = 0; - cmd->scsi_cmd_pa_prevent = allow ? 0 : 1; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - - tgt->cur_cmd = SCSI_CMD_PREVENT_ALLOW_REMOVAL; - - scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); -} - -int scsi_format_unit( tgt, mode, vuqe, intlv, ior) - register target_info_t *tgt; - int mode, vuqe; - register unsigned int intlv; - io_req_t ior; -{ - scsi_cmd_format_t *cmd; - char *parms; - - cmd = (scsi_cmd_format_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_FORMAT_UNIT; - cmd->scsi_cmd_lun_and_lba1 = - mode & (SCSI_CMD_FMT_FMTDATA|SCSI_CMD_FMT_CMPLIST|SCSI_CMD_FMT_LIST_TYPE); - cmd->scsi_cmd_lba2 = vuqe; - cmd->scsi_cmd_lba3 = intlv >> 8; - cmd->scsi_cmd_xfer_len = intlv; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - parms = (char*) cmd + 1; - if (ior->io_count) - bcopy(ior->io_data, parms, ior->io_count); - else - bzero(parms, 0xff - sizeof(*cmd)); - - tgt->cur_cmd = SCSI_CMD_FORMAT_UNIT; - - scsi_go_and_wait(tgt, sizeof(*cmd) + ior->io_count, 0, ior); - return tgt->done; -} - - -/* Group 1 Commands */ - -void scsi_long_read( tgt, secno, ior) - register target_info_t *tgt; - register unsigned int secno; - io_req_t ior; -{ - scsi_cmd_long_read_t *cmd; - register unsigned len, n_blks; - unsigned int max_dma_data; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - if (len < tgt->block_size) - len = tgt->block_size; - n_blks = len /tgt->block_size; - - cmd = (scsi_cmd_long_read_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_LONG_READ; - cmd->scsi_cmd_lun_and_relbit = 0; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = n_blks >> 8; - cmd->scsi_cmd_xfer_len_2 = n_blks; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_LONG_READ; - - scsi_go(tgt, sizeof(*cmd), len, FALSE); -} - -void scsi_long_write( tgt, secno, ior) - register target_info_t *tgt; - register unsigned int secno; - io_req_t ior; -{ - scsi_cmd_long_write_t *cmd; - unsigned len; /* in bytes */ - unsigned int max_dma_data, n_blks; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - if (len < tgt->block_size) - len = tgt->block_size; - n_blks = len /tgt->block_size; - - cmd = (scsi_cmd_long_write_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_LONG_WRITE; - cmd->scsi_cmd_lun_and_relbit = 0; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = n_blks >> 8; - cmd->scsi_cmd_xfer_len_2 = n_blks; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_LONG_WRITE; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - -int scdisk_verify( tgt, secno, nsectrs, ior) - register target_info_t *tgt; - int secno, nsectrs; - io_req_t ior; -{ - scsi_cmd_verify_long_t *cmd; - int len; - - len = ior->io_count; - - cmd = (scsi_cmd_verify_long_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_VERIFY_1; - cmd->scsi_cmd_lun_and_relbit = len ? SCSI_CMD_VFY_BYTCHK : 0; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = (nsectrs) >> 8; - cmd->scsi_cmd_xfer_len_2 = nsectrs; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_VERIFY_1; - - scsi_go_and_wait(tgt, sizeof(*cmd) + len, 0, ior); - return tgt->done; -} - - -int scsi_read_defect( tgt, mode, ior) - register target_info_t *tgt; - register unsigned int mode; - io_req_t ior; -{ - scsi_cmd_long_read_t *cmd; - register unsigned len; - - len = ior->io_count; - if (len > 0xffff) - len = 0xffff; - - cmd = (scsi_cmd_read_defect_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_READ_DEFECT_DATA; - cmd->scsi_cmd_lun_and_relbit = 0; - cmd->scsi_cmd_lba1 = mode & 0x1f; - cmd->scsi_cmd_lba2 = 0; - cmd->scsi_cmd_lba3 = 0; - cmd->scsi_cmd_lba4 = 0; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = (len) >> 8; - cmd->scsi_cmd_xfer_len_2 = (len); - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - /* ++ HACK Alert */ -/* tgt->cur_cmd = SCSI_CMD_READ_DEFECT_DATA;*/ - tgt->cur_cmd = SCSI_CMD_LONG_READ; - /* -- HACK Alert */ - - scsi_go(tgt, sizeof(*cmd), len, FALSE); - iowait(ior); - return tgt->done; -} - - -#if 0 /* unused commands */ -scsi_rezero_unit( tgt, ior) - register target_info_t *tgt; - io_req_t ior; -{ - scsi_cmd_rezero_t *cmd; - - cmd = (scsi_cmd_rezero_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_REZERO_UNIT; - cmd->scsi_cmd_lun_and_lba1 = 0; - cmd->scsi_cmd_lba2 = 0; - cmd->scsi_cmd_lba3 = 0; - cmd->scsi_cmd_xfer_len = 0; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - - tgt->cur_cmd = SCSI_CMD_REZERO_UNIT; - - scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); - -} - -scsi_seek( tgt, where, ior) - register target_info_t *tgt; - register unsigned int where; - io_req_t ior; -{ - scsi_cmd_seek_t *cmd; - - cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_SEEK; - cmd->scsi_cmd_lun_and_lba1 = (where >> 16) & 0x1f; - cmd->scsi_cmd_lba2 = where >> 8; - cmd->scsi_cmd_lba3 = where; - cmd->scsi_cmd_xfer_len = 0; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - - tgt->cur_cmd = SCSI_CMD_SEEK; - - scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); - -} - -scsi_reserve( tgt, len, id, mode, ior) - register target_info_t *tgt; - register unsigned int len; - unsigned char id; - io_req_t ior; -{ - scsi_cmd_reserve_t *cmd; - - cmd = (scsi_cmd_reserve_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_RESERVE; - cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f; - cmd->scsi_cmd_reserve_id = id; - cmd->scsi_cmd_extent_llen1 = len >> 8; - cmd->scsi_cmd_extent_llen2 = len; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - - tgt->cur_cmd = SCSI_CMD_RESERVE; - - scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); - -} - -scsi_release( tgt, id, mode, ior) - register target_info_t *tgt; - unsigned char id, mode; - io_req_t ior; -{ - scsi_cmd_release_t *cmd; - - cmd = (scsi_cmd_release_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_RELEASE; - cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f; - cmd->scsi_cmd_reserve_id = id; - cmd->scsi_cmd_lba3 = 0; - cmd->scsi_cmd_xfer_len = 0; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - - tgt->cur_cmd = SCSI_CMD_RELEASE; - - scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior); - -} - - -/* Group 1 Commands */ - -scsi_long_seek( tgt, secno, ior) - register target_info_t *tgt; - io_req_t ior; -{ - scsi_cmd_long_seek_t *cmd; - - cmd = (scsi_cmd_long_seek_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_LONG_SEEK; - cmd->scsi_cmd_lun_and_relbit = 0; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = 0; - cmd->scsi_cmd_xfer_len_2 = 0; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_LONG_SEEK; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - -scsi_write_verify( tgt, secno, ior) - register target_info_t *tgt; - io_req_t ior; -{ - scsi_cmd_write_vfy_t *cmd; - unsigned len; /* in bytes */ - unsigned int max_dma_data, n_blks; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - if (len < tgt->block_size) - len = tgt->block_size; - n_blks = len / tgt->block_size; - - cmd = (scsi_cmd_write_vfy_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_WRITE_AND_VERIFY; - cmd->scsi_cmd_lun_and_relbit = SCSI_CMD_VFY_BYTCHK; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = n_blks >> 8; - cmd->scsi_cmd_xfer_len_2 = n_blks; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_WRITE_AND_VERIFY; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - -scsi_search_data( tgt, secno, how, flags, ior) - register target_info_t *tgt; - io_req_t ior; -{ - scsi_cmd_search_t *cmd; - unsigned len; /* in bytes */ - unsigned int max_dma_data, n_blks; - - max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data; - - if (how != SCSI_CMD_SEARCH_HIGH && - how != SCSI_CMD_SEARCH_EQUAL && - how != SCSI_CMD_SEARCH_LOW) - panic("scsi_search_data"); - - len = ior->io_count; - if (len > max_dma_data) - len = max_dma_data; - n_blks = len / tgt->block_size; - - cmd = (scsi_cmd_search_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = how; - cmd->scsi_cmd_lun_and_relbit = flags & 0x1e; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = n_blks >> 8; - cmd->scsi_cmd_xfer_len_2 = n_blks; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = how; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - - -scsi_set_limits( tgt, secno, nblocks, inhibit, ior) - register target_info_t *tgt; - io_req_t ior; -{ - scsi_cmd_set_limits_t *cmd; - - cmd = (scsi_cmd_set_limits_t*) (tgt->cmd_ptr); - cmd->scsi_cmd_code = SCSI_CMD_SET_LIMITS; - cmd->scsi_cmd_lun_and_relbit = inhibit & 0x3; - cmd->scsi_cmd_lba1 = secno >> 24; - cmd->scsi_cmd_lba2 = secno >> 16; - cmd->scsi_cmd_lba3 = secno >> 8; - cmd->scsi_cmd_lba4 = secno; - cmd->scsi_cmd_xxx = 0; - cmd->scsi_cmd_xfer_len_1 = nblocks >> 8; - cmd->scsi_cmd_xfer_len_2 = nblocks; - cmd->scsi_cmd_ctrl_byte = 0; /* not linked */ - - tgt->cur_cmd = SCSI_CMD_SET_LIMITS; - - scsi_go(tgt, sizeof(*cmd), 0, FALSE); -} - - -#endif - -#ifdef SCSI2 -scsi_lock_cache -scsi_prefetch -scsi_read_defect_data -scsi_sync_cache -scsi_write_same -#endif SCSI2 -#endif /* NSCSI > 0 */ |