diff options
Diffstat (limited to 'src/input/vcd/libcdio/FreeBSD/freebsd_cam.c')
-rw-r--r-- | src/input/vcd/libcdio/FreeBSD/freebsd_cam.c | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/src/input/vcd/libcdio/FreeBSD/freebsd_cam.c b/src/input/vcd/libcdio/FreeBSD/freebsd_cam.c deleted file mode 100644 index 68e38ccae..000000000 --- a/src/input/vcd/libcdio/FreeBSD/freebsd_cam.c +++ /dev/null @@ -1,346 +0,0 @@ -/* - $Id: freebsd_cam.c,v 1.1 2005/01/01 02:43:57 rockyb Exp $ - - Copyright (C) 2004 Rocky Bernstein <rocky@panix.com> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -/* This file contains FreeBSD-specific code and implements low-level - control of the CD drive via SCSI emulation. -*/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -static const char _rcsid[] = "$Id: freebsd_cam.c,v 1.1 2005/01/01 02:43:57 rockyb Exp $"; - -#ifdef HAVE_FREEBSD_CDROM - -#include "freebsd.h" -#include <cdio/scsi_mmc.h> - -/* Default value in seconds we will wait for a command to - complete. */ -#define DEFAULT_TIMEOUT_MSECS 10000 - -/*! - Run a SCSI MMC command. - - p_user_data internal CD structure. - i_timeout_ms time in milliseconds we will wait for the command - to complete. If this value is -1, use the default - time-out value. - i_cdb Size of p_cdb - p_cdb CDB bytes. - e_direction direction the transfer is to go. - i_buf Size of buffer - p_buf Buffer for data, both sending and receiving - - Return 0 if no error. - */ -int -run_scsi_cmd_freebsd_cam( const void *p_user_data, unsigned int i_timeout_ms, - unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb, - scsi_mmc_direction_t e_direction, - unsigned int i_buf, /*in/out*/ void *p_buf ) -{ - const _img_private_t *p_env = p_user_data; - int i_status; - int direction = CAM_DEV_QFRZDIS; - union ccb ccb; - - if (!p_env || !p_env->cam) return -2; - - memset(&ccb, 0, sizeof(ccb)); - - ccb.ccb_h.path_id = p_env->cam->path_id; - ccb.ccb_h.target_id = p_env->cam->target_id; - ccb.ccb_h.target_lun = p_env->cam->target_lun; - ccb.ccb_h.timeout = i_timeout_ms; - - if (!i_cdb) - direction |= CAM_DIR_NONE; - else - direction |= (e_direction == SCSI_MMC_DATA_READ)?CAM_DIR_IN : CAM_DIR_OUT; - cam_fill_csio (&(ccb.csio), 1, NULL, - direction | CAM_DEV_QFRZDIS, MSG_SIMPLE_Q_TAG, p_buf, i_buf, - sizeof(ccb.csio.sense_data), 0, 30*1000); - - memcpy(ccb.csio.cdb_io.cdb_bytes, p_cdb, i_cdb); - - ccb.csio.cdb_len = - scsi_mmc_get_cmd_len(ccb.csio.cdb_io.cdb_bytes[0]); - - if ((i_status = cam_send_ccb(p_env->cam, &ccb)) < 0) - { - cdio_warn ("transport failed: %d", i_status); - return -1; - } - if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) - { - return 0; - } - errno = EIO; - i_status = ERRCODE(((unsigned char *)&ccb.csio.sense_data)); - if (i_status == 0) - i_status = -1; - else - CREAM_ON_ERRNO(((unsigned char *)&ccb.csio.sense_data)); - cdio_warn ("transport failed: %d", i_status); - return i_status; -} - -bool -init_freebsd_cam (_img_private_t *p_env) -{ - char pass[100]; - - p_env->cam=NULL; - memset (&p_env->ccb, 0, sizeof(p_env->ccb)); - p_env->ccb.ccb_h.func_code = XPT_GDEVLIST; - - if (-1 == p_env->gen.fd) - p_env->gen.fd = open (p_env->device, O_RDONLY, 0); - - if (p_env->gen.fd < 0) - { - cdio_warn ("open (%s): %s", p_env->device, strerror (errno)); - return false; - } - - if (ioctl (p_env->gen.fd, CAMGETPASSTHRU, &p_env->ccb) < 0) - { - cdio_warn ("open: %s", strerror (errno)); - return false; - } - sprintf (pass,"/dev/%.15s%u", - p_env->ccb.cgdl.periph_name, - p_env->ccb.cgdl.unit_number); - p_env->cam = cam_open_pass (pass,O_RDWR,NULL); - if (!p_env->cam) return false; - - p_env->gen.init = true; - p_env->b_cam_init = true; - return true; -} - -void -free_freebsd_cam (void *user_data) -{ - _img_private_t *p_env = user_data; - - if (NULL == p_env) return; - - if (p_env->gen.fd > 0) - close (p_env->gen.fd); - p_env->gen.fd = -1; - - if(p_env->cam) - cam_close_device(p_env->cam); - - free (p_env); -} - -static int -_set_bsize (_img_private_t *p_env, unsigned int bsize) -{ - scsi_mmc_cdb_t cdb = {{0, }}; - - struct - { - uint8_t reserved1; - uint8_t medium; - uint8_t reserved2; - uint8_t block_desc_length; - uint8_t density; - uint8_t number_of_blocks_hi; - uint8_t number_of_blocks_med; - uint8_t number_of_blocks_lo; - uint8_t reserved3; - uint8_t block_length_hi; - uint8_t block_length_med; - uint8_t block_length_lo; - } mh; - - memset (&mh, 0, sizeof (mh)); - mh.block_desc_length = 0x08; - mh.block_length_hi = (bsize >> 16) & 0xff; - mh.block_length_med = (bsize >> 8) & 0xff; - mh.block_length_lo = (bsize >> 0) & 0xff; - - memset (&cdb, 0, sizeof (cdb)); - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_MODE_SELECT_6); - - cdb.field[1] = 1 << 4; - cdb.field[4] = 12; - - return run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, SCSI_MMC_DATA_WRITE, - sizeof(mh), &mh); -} - -int -read_mode2_sector_freebsd_cam (_img_private_t *p_env, void *data, lsn_t lsn, - bool b_form2) -{ - if ( b_form2 ) - return read_mode2_sectors_freebsd_cam(p_env, data, lsn, 1); - else { - /* Need to pick out the data portion from a mode2 form2 frame */ - char buf[M2RAW_SECTOR_SIZE] = { 0, }; - int retval = read_mode2_sectors_freebsd_cam(p_env, buf, lsn, 1); - if ( retval ) return retval; - memcpy (((char *)data), buf + CDIO_CD_SUBHEADER_SIZE, CDIO_CD_FRAMESIZE); - return 0; - } -} - -/*! - Reads nblocks of mode2 sectors from cd device into data starting - from lsn. - Returns 0 if no error. - */ -int -read_mode2_sectors_freebsd_cam (_img_private_t *p_env, void *p_buf, - lsn_t lsn, unsigned int nblocks) -{ - scsi_mmc_cdb_t cdb = {{0, }}; - - bool b_read_10 = false; - - CDIO_MMC_SET_READ_LBA(cdb.field, lsn); - - if (b_read_10) { - int retval; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_10); - CDIO_MMC_SET_READ_LENGTH16(cdb.field, nblocks); - if ((retval = _set_bsize (p_env, M2RAW_SECTOR_SIZE))) - return retval; - - if ((retval = run_scsi_cmd_freebsd_cam (p_env, 0, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, - SCSI_MMC_DATA_READ, - M2RAW_SECTOR_SIZE * nblocks, - p_buf))) - { - _set_bsize (p_env, CDIO_CD_FRAMESIZE); - return retval; - } - - if ((retval = _set_bsize (p_env, CDIO_CD_FRAMESIZE))) - return retval; - } else - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_CD); - CDIO_MMC_SET_READ_LENGTH24(cdb.field, nblocks); - cdb.field[1] = 0; /* sector size mode2 */ - cdb.field[9] = 0x58; /* 2336 mode2 */ - return run_scsi_cmd_freebsd_cam (p_env, 0, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, - SCSI_MMC_DATA_READ, - M2RAW_SECTOR_SIZE * nblocks, p_buf); - - return 0; -} - -/*! - Return the size of the CD in logical block address (LBA) units. - */ -uint32_t -stat_size_freebsd_cam (_img_private_t *p_env) -{ - scsi_mmc_cdb_t cdb = {{0, }}; - uint8_t buf[12] = { 0, }; - - uint32_t retval; - int i_status; - - /* Operation code */ - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_READ_TOC); - - cdb.field[1] = 0; /* lba; msf: 0x2 */ - - /* Format */ - cdb.field[2] = CDIO_MMC_READTOC_FMT_TOC; - - CDIO_MMC_SET_START_TRACK(cdb.field, CDIO_CDROM_LEADOUT_TRACK); - - CDIO_MMC_SET_READ_LENGTH16(cdb.field, sizeof(buf)); - - p_env->ccb.csio.data_ptr = buf; - p_env->ccb.csio.dxfer_len = sizeof (buf); - - i_status = run_scsi_cmd_freebsd_cam(p_env, DEFAULT_TIMEOUT_MSECS, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, SCSI_MMC_DATA_READ, - sizeof(buf), buf); - if (0 != i_status) - return 0; - - { - int i; - - retval = 0; - for (i = 8; i < 12; i++) - { - retval <<= 8; - retval += buf[i]; - } - } - - return retval; -} - -/*! - * Eject using SCSI MMC commands. Return 0 if successful. - */ -int -eject_media_freebsd_cam (_img_private_t *p_env) -{ - int i_status; - scsi_mmc_cdb_t cdb = {{0, }}; - uint8_t buf[1]; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_ALLOW_MEDIUM_REMOVAL); - - i_status = run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) - return i_status; - - cdb.field[4] = 1; - i_status = run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS, - scsi_mmc_get_cmd_len(cdb.field[0]), &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); - if (0 != i_status) - return i_status; - - CDIO_MMC_SET_COMMAND(cdb.field, CDIO_MMC_GPCMD_START_STOP); - cdb.field[4] = 2; /* eject */ - - return run_scsi_cmd_freebsd_cam (p_env, DEFAULT_TIMEOUT_MSECS, - scsi_mmc_get_cmd_len(cdb.field[0]), - &cdb, - SCSI_MMC_DATA_WRITE, 0, &buf); -} - -#endif /* HAVE_FREEBSD_CDROM */ |