1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-20 00:21:35 +00:00

k3b-kde4: Update the libk3bdevice/k3bscsicommandbsd.cpp patch.

I committed a6a2ed3 to k3b's git tree some time ago. It is a patch by
avg@ improving the file and preventing some bugs from occurring. In
his own words in KDE git review request 103293:

  Main idea of the change is to improve the case where SCSI sense data
  is not automatically provided and has to be explicitly requested.
  Current code essentially duplicates main transport code for this
  task.  The proposed code recursively calls into the transport code
  with MMC_REQUEST_SENSE command.  This also fixes a problem with the
  existing code where it re-uses a CCB of the original command for sense
  fetching but doesn't ensure that all the previously used bytes are
  reset to proper values.  This can result in a malformed
  MMC_REQUEST_SENSE CCB which can confuse certain hardware (e.g. it
  hangs Optiarc DVD RW AD-7191S 1.02).  Also the style of the code is
  cleaned up.  Because of the code re-use the code is now more compact.
  Additionally some historic and useless code was dropped - the code for
  setting errno.  errno value is not used by the calling code and this
  is an artifact of the FreeBSD-specific code having been borrowed from
  a different project (as attested by Heiner Eichmann
  <h.eichmann@gmx.de>).

The current patch in the port now contains both commits 4ffc589 and
a6a2ed3 squashed together.

Bump PORTREVISION accordingly.

Submitted by:	avg
This commit is contained in:
Raphael Kubo da Costa 2012-02-11 18:13:11 +00:00
parent 46d560e64b
commit 555cbea998
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=290934
2 changed files with 252 additions and 63 deletions

View File

@ -7,7 +7,7 @@
PORTNAME= k3b
PORTVERSION= 2.0.2
PORTREVISION= 5
PORTREVISION= 6
CATEGORIES= sysutils multimedia kde
MASTER_SITES= SF/${PORTNAME}/${PORTNAME}/${PORTVERSION}

View File

@ -1,95 +1,284 @@
commit d8f73a5f66c6bbebac52a8b784affb106b188279
Author: Raphael Kubo da Costa <rakuco@FreeBSD.org>
Date: Fri Oct 28 00:16:58 2011 -0200
k3bscsicommand_bsd: Do not access the scsi_sense_data fields manually.
cam users are expected to retrieve those values with scsi_extract_sense
(or, since FreeBSD 9, scsi_extract_sense_len).
FreeBSD 9 has changed the scsi_sense_data struct, but everything works
fine in all supported releases if we just use scsi_extract_sense.
CCMAIL: michalm@jabster.pl
diff --git a/libk3bdevice/k3bscsicommand_bsd.cpp b/libk3bdevice/k3bscsicommand_bsd.cpp
index ce6508e..52eda04 100644
index ce6508e..63a8fd5 100644
--- ./libk3bdevice/k3bscsicommand_bsd.cpp
+++ ./libk3bdevice/k3bscsicommand_bsd.cpp
@@ -103,16 +103,16 @@ int K3b::Device::ScsiCommand::transport( TransportDirection dir,
m_device->usageUnlock();
@@ -1,6 +1,7 @@
/*
*
* Copyright (C) 2003-2009 Sebastian Trueg <trueg@k3b.org>
+ * Copyright (C) 2011 Andriy Gapon <avg@FreeBSD.org>
*
* This file is part of the K3b project.
* Copyright (C) 1998-2009 Sebastian Trueg <trueg@k3b.org>
@@ -23,41 +24,43 @@
#include <cam/scsi/scsi_message.h>
#include <cam/scsi/scsi_pass.h>
struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
-#define ERRCODE(s) ((((s)[2]&0x0F)<<16)|((s)[12]<<8)|((s)[13]))
-#define EMEDIUMTYPE EINVAL
-#define ENOMEDIUM ENODEV
-#define CREAM_ON_ERRNO(s) do { \
- switch ((s)[12]) \
- { case 0x04: errno=EAGAIN; break; \
- case 0x20: errno=ENODEV; break; \
- case 0x21: if ((s)[13]==0) errno=ENOSPC; \
- else errno=EINVAL; \
- break; \
- case 0x30: errno=EMEDIUMTYPE; break; \
- case 0x3A: errno=ENOMEDIUM; break; \
- } \
- } while(0)
-
+namespace /*anonymous*/
+{
+ inline int sense_to_err( const struct scsi_sense_data& s )
+ {
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( (struct scsi_sense_data*) &s, &errorCode,
+ &senseKey, &addSenseCode, &addSenseCodeQual );
+ return (errorCode << 24) | (senseKey << 16) |
+ (addSenseCode << 8) | addSenseCodeQual;
+ }
+}
class K3b::Device::ScsiCommand::Private
{
+ typedef union ccb CCB;
+
public:
- union ccb ccb;
+ Private();
+ int transport( const Device* device, TransportDirection dir, void* data, size_t len );
+ unsigned char& operator[]( size_t i );
+ void clear();
+ const CCB& get_ccb() { return ccb; }
+
+private:
+ CCB ccb;
};
void K3b::Device::ScsiCommand::clear()
{
- memset (&d->ccb,0,sizeof(ccb));
+ d->clear();
}
-
unsigned char& K3b::Device::ScsiCommand::operator[]( size_t i )
{
- if( d->ccb.csio.cdb_len < i+1 )
- d->ccb.csio.cdb_len = i+1;
- return d->ccb.csio.cdb_io.cdb_bytes[i];
+ return (*d)[i];
}
int K3b::Device::ScsiCommand::transport( TransportDirection dir,
@@ -78,130 +81,102 @@ int K3b::Device::ScsiCommand::transport( TransportDirection dir,
m_device->usageUnlock();
return -1;
}
- d->ccb.ccb_h.path_id = m_device->handle()->path_id;
- d->ccb.ccb_h.target_id = m_device->handle()->target_id;
- d->ccb.ccb_h.target_lun = m_device->handle()->target_lun;
- kDebug() << "(K3b::Device::ScsiCommand) transport command " << QString::number((int)d->ccb.csio.cdb_io.cdb_bytes[0], 16) << ", length: " << (int)d->ccb.csio.cdb_len;
- int ret=0;
- int direction = CAM_DEV_QFRZDIS;
- if (!len)
- direction |= CAM_DIR_NONE;
- else
- direction |= (dir & TR_DIR_READ)?CAM_DIR_IN : CAM_DIR_OUT;
- cam_fill_csio (&(d->ccb.csio), 1, 0 /* NULL */, direction, MSG_SIMPLE_Q_TAG, (u_int8_t *)data, len, sizeof(d->ccb.csio.sense_data), d->ccb.csio.cdb_len, 30*1000);
- unsigned char * sense = (unsigned char *)&d->ccb.csio.sense_data;
+ int ret = d->transport( m_device, dir, data, len );
+ if( ret != 0 ) {
+ const struct scsi_sense_data& s = d->get_ccb().csio.sense_data;
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( (struct scsi_sense_data*) &s, &errorCode, &senseKey,
+ &addSenseCode, &addSenseCodeQual );
+ debugError( d->get_ccb().csio.cdb_io.cdb_bytes[0],
+ errorCode,
+ senseKey,
+ addSenseCode,
+ addSenseCodeQual );
+ }
- ret = cam_send_ccb(m_device->handle(), &d->ccb);
+ if( needToClose )
+ m_device->close();
+ m_device->usageUnlock();
- if (ret < 0) {
- kDebug() << "(K3b::Device::ScsiCommand) transport failed: " << ret;
+ return ret;
+}
- if( needToClose )
- m_device->close();
+K3b::Device::ScsiCommand::Private::Private()
+{
+ clear();
+}
- m_device->usageUnlock();
+void K3b::Device::ScsiCommand::Private::clear()
+{
+ memset( &ccb, 0, sizeof(ccb) );
+}
- struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
- debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
- senset->error_code & SSD_ERRCODE,
- senset->flags & SSD_KEY,
- senset->add_sense_code,
- senset->add_sense_code_qual );
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( senset, &errorCode, &senseKey, &addSenseCode,
+ &addSenseCodeQual );
+ debugError( d->ccb.csio.cdb_io.cdb_bytes[0], errorCode, senseKey,
+ addSenseCode, addSenseCodeQual );
+unsigned char& K3b::Device::ScsiCommand::Private::operator[]( size_t i )
+{
+ if( ccb.csio.cdb_len < i + 1 )
+ ccb.csio.cdb_len = i + 1;
+ return ccb.csio.cdb_io.cdb_bytes[i];
+}
- int result = (((senset->error_code & SSD_ERRCODE)<<24) & 0xF000 |
- ((senset->flags & SSD_KEY)<<16) & 0x0F00 |
- (senset->add_sense_code<<8) & 0x00F0 |
- (senset->add_sense_code_qual) & 0x000F );
+ int result = ((errorCode<<24) & 0xF000 |
+ (senseKey<<16) & 0x0F00 |
+ (addSenseCode<<8) & 0x00F0 |
+ (addSenseCodeQual) & 0x000F );
+int K3b::Device::ScsiCommand::Private::transport( const Device* device, TransportDirection dir, void* data, size_t len )
+{
+ ccb.ccb_h.path_id = device->handle()->path_id;
+ ccb.ccb_h.target_id = device->handle()->target_id;
+ ccb.ccb_h.target_lun = device->handle()->target_lun;
return result ? result : ret;
- return result ? result : ret;
+ kDebug() << "(K3b::Device::ScsiCommand) transport command " << commandString(ccb.csio.cdb_io.cdb_bytes[0])
+ << " (" << QString::number((int)ccb.csio.cdb_io.cdb_bytes[0], 16) << "), length: " << (int)ccb.csio.cdb_len;
+ int direction = CAM_DEV_QFRZDIS;
+ if (!len)
+ direction |= CAM_DIR_NONE;
+ else
+ direction |= (dir & TR_DIR_READ) ? CAM_DIR_IN : CAM_DIR_OUT;
+
+ cam_fill_csio( &(ccb.csio), 1, NULL, direction, MSG_SIMPLE_Q_TAG, (uint8_t*)data, len, sizeof(ccb.csio.sense_data), ccb.csio.cdb_len, 30*1000 );
+ int ret = cam_send_ccb( device->handle(), &ccb );
+ if( ret < 0 ) {
+ kError() << "(K3b::Device::ScsiCommand) transport cam_send_ccb failed: ret = " << ret
+ << ", errno = " << errno << ", cam_errbuf = " << cam_errbuf;
+ return 1;
}
@@ -152,11 +152,11 @@ int K3b::Device::ScsiCommand::transport( TransportDirection dir,
kDebug() << "(K3b::Device::ScsiCommand) transport failed (2): " << ret;
ret = -1;
struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
-
- else if ((d->ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
- if( needToClose )
- m_device->close();
- m_device->usageUnlock();
+ else if( (ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP ) {
+ kDebug() << "(K3b::Device::ScsiCommand) transport succeeded";
return 0;
}
- errno = EIO;
- // FreeBSD 5-CURRENT since 2003-08-24, including 5.2 fails to
- // pull sense data automatically, at least for ATAPI transport,
- // so I reach for it myself...
- if ((d->ccb.csio.scsi_status==SCSI_STATUS_CHECK_COND) &&
- !(d->ccb.ccb_h.status&CAM_AUTOSNS_VALID))
- {
- u_int8_t _sense[18];
- u_int32_t resid=d->ccb.csio.resid;
-
- memset(_sense,0,sizeof(_sense));
+ kDebug() << "(K3b::Device::ScsiCommand) transport command failed: scsi_status = " << QString::number(ccb.csio.scsi_status, 16);
- operator[](0) = 0x03; // REQUEST SENSE
- d->ccb.csio.cdb_io.cdb_bytes[4] = sizeof(_sense);
- d->ccb.csio.cdb_len = 6;
- d->ccb.csio.ccb_h.flags |= CAM_DIR_IN|CAM_DIS_AUTOSENSE;
- d->ccb.csio.data_ptr = _sense;
- d->ccb.csio.dxfer_len = sizeof(_sense);
- d->ccb.csio.sense_len = 0;
+ if( ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND &&
+ !(ccb.ccb_h.status & CAM_AUTOSNS_VALID) &&
+ ccb.csio.cdb_io.cdb_bytes[0] != MMC_REQUEST_SENSE )
+ {
+ kDebug() << "(K3b::Device::ScsiCommand) transport requesting sense data";
- ret = cam_send_ccb(m_device->handle(), &d->ccb);
+ struct scsi_sense_data sense;
+ ScsiCommand::Private cmd;
+ cmd[0] = MMC_REQUEST_SENSE;
+ cmd[4] = SSD_MIN_SIZE;
+ cmd[5] = 0; // Necessary to set the proper command length
- d->ccb.csio.resid = resid;
- if (ret<0)
- {
- kDebug() << "(K3b::Device::ScsiCommand) transport failed (2): " << ret;
- ret = -1;
- struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
- debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
- senset->error_code & SSD_ERRCODE,
- senset->flags & SSD_KEY,
- senset->add_sense_code,
- senset->add_sense_code_qual );
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( senset, &errorCode, &senseKey, &addSenseCode,
+ &addSenseCodeQual );
+ debugError( d->ccb.csio.cdb_io.cdb_bytes[0], errorCode, senseKey,
+ addSenseCode, addSenseCodeQual );
if( needToClose )
m_device->close();
@@ -170,11 +170,11 @@ int K3b::Device::ScsiCommand::transport( TransportDirection dir,
errno=EIO,-1;
ret = -1;
struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
-
- if( needToClose )
- m_device->close();
- m_device->usageUnlock();
-
- return -1;
- }
- if ((d->ccb.ccb_h.status&CAM_STATUS_MASK) != CAM_REQ_CMP)
+ memset( &sense, 0, sizeof(sense) );
+ ret = cmd.transport( device, TR_DIR_READ, &sense, SSD_MIN_SIZE );
+ if( ret < 0 )
{
- kDebug() << "(K3b::Device::ScsiCommand) transport failed (3): " << ret;
- errno=EIO,-1;
- ret = -1;
- struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
- debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
- senset->error_code & SSD_ERRCODE,
- senset->flags & SSD_KEY,
- senset->add_sense_code,
- senset->add_sense_code_qual );
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( senset, &errorCode, &senseKey, &addSenseCode,
+ &addSenseCodeQual );
+ debugError( d->ccb.csio.cdb_io.cdb_bytes[0], errorCode, senseKey,
+ addSenseCode, addSenseCodeQual );
-
- if( needToClose )
- m_device->close();
- m_device->usageUnlock();
-
- return -1;
+ kWarning() << "(K3b::Device::ScsiCommand) transport getting sense data failed: " << ret;
+ return 1;
}
if( needToClose )
m_device->close();
@@ -193,11 +193,11 @@ int K3b::Device::ScsiCommand::transport( TransportDirection dir,
else
CREAM_ON_ERRNO(((unsigned char *)&d->ccb.csio.sense_data));
struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
- memcpy(sense,_sense,sizeof(_sense));
+ ccb.csio.sense_data = sense;
+ ccb.ccb_h.status |= CAM_AUTOSNS_VALID;
}
- ret = ERRCODE(sense);
- kDebug() << "(K3b::Device::ScsiCommand) transport failed (4): " << ret;
- if (ret == 0)
- ret = -1;
- else
- CREAM_ON_ERRNO(((unsigned char *)&d->ccb.csio.sense_data));
- struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
- debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
- senset->error_code & SSD_ERRCODE,
- senset->flags & SSD_KEY,
- senset->add_sense_code,
- senset->add_sense_code_qual );
+ int errorCode, senseKey, addSenseCode, addSenseCodeQual;
+ scsi_extract_sense( senset, &errorCode, &senseKey, &addSenseCode,
+ &addSenseCodeQual );
+ debugError( d->ccb.csio.cdb_io.cdb_bytes[0], errorCode, senseKey,
+ addSenseCode, addSenseCodeQual );
-
- if( needToClose )
- m_device->close();
- m_device->usageUnlock();
+ if( !(ccb.ccb_h.status & CAM_AUTOSNS_VALID) )
+ kDebug() << "(K3b::Device::ScsiCommand) sense data is not available";
if( needToClose )
m_device->close();
+ ret = sense_to_err(ccb.csio.sense_data);
+ if( ret == 0 )
+ ret = 1;
+ kDebug() << "(K3b::Device::ScsiCommand) transport failed: " << ret;
return ret;
}