Exemplo n.º 1
0
BraseroScsiResult
brasero_scsi_command_issue_sync (gpointer command,
				 gpointer buffer,
				 int size,
				 BraseroScsiErrCode *error)
{
	scsireq_t req;
	BraseroScsiResult res;
	BraseroScsiCmd *cmd;

	cmd = command;
	brasero_sg_command_setup (&req,
				  cmd,
				  buffer,
				  size);

	res = ioctl (cmd->handle->fd, SCIOCCOMMAND, &req);
	if (res == -1) {
		BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_ERRNO);
		return BRASERO_SCSI_FAILURE;
	}

	if (req.retsts == SCCMD_OK)
		return BRASERO_SCSI_OK;

	if (req.retsts == SCCMD_SENSE)
		return brasero_sense_data_process (req.sense, error);

	return BRASERO_SCSI_FAILURE;
}
Exemplo n.º 2
0
BraseroScsiResult
brasero_scsi_command_issue_sync (gpointer command,
				 gpointer buffer,
				 int size,
				 BraseroScsiErrCode *error)
{
	uchar sense_buffer [BRASERO_SENSE_DATA_SIZE];
	struct sg_io_hdr transport;
	BraseroScsiResult res;
	BraseroScsiCmd *cmd;

	g_return_val_if_fail (command != NULL, BRASERO_SCSI_FAILURE);

	cmd = command;
	brasero_sg_command_setup (&transport,
				  sense_buffer,
				  cmd,
				  buffer,
				  size);

	/* NOTE on SG_IO: only for TEST UNIT READY, REQUEST/MODE SENSE, INQUIRY,
	 * READ CAPACITY, READ BUFFER, READ and LOG SENSE are allowed with it */
	res = ioctl (cmd->handle->fd, SG_IO, &transport);
	if (res) {
		BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_ERRNO);
		return BRASERO_SCSI_FAILURE;
	}

	if ((transport.info & SG_INFO_OK_MASK) == SG_INFO_OK)
		return BRASERO_SCSI_OK;

	if ((transport.masked_status & CHECK_CONDITION) && transport.sb_len_wr)
		return brasero_sense_data_process (sense_buffer, error);

	return BRASERO_SCSI_FAILURE;
}
Exemplo n.º 3
0
static BraseroScsiResult
brasero_get_performance (BraseroGetPerformanceCDB *cdb,
			 gint sizeof_descriptors,
			 BraseroScsiGetPerfData **data,
			 int *data_size,
			 BraseroScsiErrCode *error)
{
	BraseroScsiGetPerfData *buffer;
	BraseroScsiGetPerfHdr hdr;
	BraseroScsiResult res;
	int request_size;
	int buffer_size;

	if (!data || !data_size) {
		BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_BAD_ARGUMENT);
		return BRASERO_SCSI_FAILURE;
	}

	/* Issue the command once to get the size ... */
	memset (&hdr, 0, sizeof (hdr));
	BRASERO_SET_16 (cdb->max_desc, 0);
	res = brasero_scsi_command_issue_sync (cdb, &hdr, sizeof (hdr), error);
	if (res != BRASERO_SCSI_OK)
		return res;

	/* ... get the request size ... */
	request_size = BRASERO_GET_32 (hdr.len) +
		       G_STRUCT_OFFSET (BraseroScsiGetPerfHdr, len) +
		       sizeof (hdr.len);

	/* ... get the answer itself. */
	buffer = brasero_get_performance_get_buffer (cdb,
						     sizeof_descriptors,
						     &hdr,
						     error);
	if (!buffer)
		return BRASERO_SCSI_FAILURE;

	/* make sure the response has the requested size */
	buffer_size = BRASERO_GET_32 (buffer->hdr.len) +
		      G_STRUCT_OFFSET (BraseroScsiGetPerfHdr, len) +
		      sizeof (buffer->hdr.len);

	if (request_size < buffer_size) {
		BraseroScsiGetPerfData *new_buffer;

		/* Strangely some drives returns a buffer size that is bigger
		 * than the one they returned on the first time. So redo whole
		 * operation again but this time with the new size we got */
		BRASERO_MEDIA_LOG ("Sizes mismatch asked %i / received %i\n"
				   "Re-issuing the command with received size",
				   request_size,
				   buffer_size);

		/* Try to get a new buffer of the new size */
		memcpy (&hdr, &buffer->hdr, sizeof (hdr));
		new_buffer = brasero_get_performance_get_buffer (cdb,
		                                         	 sizeof_descriptors,
		                                                 &hdr,
		                                                 error);
		if (new_buffer) {
			g_free (buffer);
			buffer = new_buffer;

			request_size = buffer_size;
			buffer_size = BRASERO_GET_32 (buffer->hdr.len) +
				      G_STRUCT_OFFSET (BraseroScsiGetPerfHdr, len) +
				      sizeof (buffer->hdr.len);
		}
	}
	else if (request_size > buffer_size)
		BRASERO_MEDIA_LOG ("Sizes mismatch asked %i / received %i",
				   request_size,
				   buffer_size);
	*data = buffer;
	*data_size = MIN (buffer_size, request_size);

	return res;
}