Beispiel #1
0
status_t
periph_simple_exec(scsi_periph_device_info* device, void* cdb, uchar cdbLength,
	void* data, size_t dataLength, int ccb_flags)
{
	SHOW_FLOW0( 0, "" );

	scsi_ccb* ccb = device->scsi->alloc_ccb(device->scsi_device);
	if (ccb == NULL)
		return B_NO_MEMORY;

	ccb->flags = ccb_flags;

	memcpy(ccb->cdb, cdb, cdbLength);
	ccb->cdb_length = cdbLength;

	ccb->sort = -1;
	ccb->timeout = device->std_timeout;

	ccb->data = (uint8*)data;
	ccb->sg_list = NULL;
	ccb->data_length = dataLength;

	status_t status = periph_safe_exec(device, ccb);

	device->scsi->free_ccb(ccb);

	return status;
}
Beispiel #2
0
static status_t
vpd_page_inquiry(scsi_periph_device_info *device, uint8 page, void* data,
	uint16 length)
{
	SHOW_FLOW0(0, "");

	scsi_ccb* ccb = device->scsi->alloc_ccb(device->scsi_device);
	if (ccb == NULL)
		return B_NO_MEMORY;

	scsi_cmd_inquiry *cmd = (scsi_cmd_inquiry *)ccb->cdb;
	memset(cmd, 0, sizeof(scsi_cmd_inquiry));
	cmd->opcode = SCSI_OP_INQUIRY;
	cmd->lun = ccb->target_lun;
	cmd->evpd = 1;
	cmd->page_code = page;
	cmd->allocation_length = length;

	ccb->flags = SCSI_DIR_IN;
	ccb->cdb_length = sizeof(scsi_cmd_inquiry);

	ccb->sort = -1;
	ccb->timeout = device->std_timeout;

	ccb->data = (uint8*)data;
	ccb->sg_list = NULL;
	ccb->data_length = length;

	status_t status = periph_safe_exec(device, ccb);

	device->scsi->free_ccb(ccb);

	return status;
}
Beispiel #3
0
status_t
periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *request)
{
	scsi_res_read_capacity capacityResult;
	scsi_cmd_read_capacity *cmd = (scsi_cmd_read_capacity *)request->cdb;
	uint64 capacity;
	uint32 blockSize;
	status_t res;

	SHOW_FLOW(3, "%p, %p", device, request);

	// driver doesn't support capacity callback - seems to be no block
	// device driver, so ignore
	if (device->callbacks->set_capacity == NULL)
		return B_OK;

	request->flags = SCSI_DIR_IN;

	request->data = (uint8*)&capacityResult;
	request->data_length = sizeof(capacityResult);
	request->cdb_length = sizeof(scsi_cmd_read_capacity);
	request->timeout = device->std_timeout;
	request->sort = -1;
	request->sg_list = NULL;

	memset(cmd, 0, sizeof(*cmd));
	cmd->opcode = SCSI_OP_READ_CAPACITY;
	// we don't set PMI (partial medium indicator) as we want the whole capacity;
	// in this case, all other parameters must be zero

	res = periph_safe_exec(device, request);

	if (res == B_DEV_MEDIA_CHANGED) {
		// in this case, the error handler has already called check_capacity
		// recursively, so we ignore our (invalid) result
		SHOW_FLOW0( 3, "ignore result because medium change" );
		return B_DEV_MEDIA_CHANGED;
	}

	ACQUIRE_BEN(&device->mutex);

	if (res == B_OK && request->data_resid == 0) {
		capacity = B_BENDIAN_TO_HOST_INT32(capacityResult.lba);

		// the command returns the index of the _last_ block,
		// i.e. the size is one larger
		++capacity;

		blockSize = B_BENDIAN_TO_HOST_INT32(capacityResult.block_size);
	} else {
		capacity = 0;
		blockSize = 0;
	}

	SHOW_FLOW(3, "capacity = %Ld, block_size = %ld", capacity, blockSize);

	device->block_size = blockSize;

	device->callbacks->set_capacity(device->periph_device,
		capacity, blockSize);

/*	device->byte2blk_shift = log2( device->block_size );
	if( device->byte2blk_shift < 0 ) {
		// this may be too restrictive...
		device->capacity = -1;
		return ERR_DEV_GENERAL;
	}*/

	RELEASE_BEN(&device->mutex);

	SHOW_FLOW(3, "done (%s)", strerror(res));

	return res;
}