aboutsummaryrefslogtreecommitdiffstats
path: root/sysutils
diff options
context:
space:
mode:
authorrakuco <rakuco@FreeBSD.org>2012-02-12 02:13:11 +0800
committerrakuco <rakuco@FreeBSD.org>2012-02-12 02:13:11 +0800
commite46a41173c08d5f8d190f502819ba8b78fe05a19 (patch)
tree573a27bfee55796ac7ba75411b372918f6ed5e2f /sysutils
parent84cb52ac428cdef4ddb83492119df0198e7e120d (diff)
downloadfreebsd-ports-gnome-e46a41173c08d5f8d190f502819ba8b78fe05a19.tar.gz
freebsd-ports-gnome-e46a41173c08d5f8d190f502819ba8b78fe05a19.tar.zst
freebsd-ports-gnome-e46a41173c08d5f8d190f502819ba8b78fe05a19.zip
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
Diffstat (limited to 'sysutils')
-rw-r--r--sysutils/k3b-kde4/Makefile2
-rw-r--r--sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp315
2 files changed, 253 insertions, 64 deletions
diff --git a/sysutils/k3b-kde4/Makefile b/sysutils/k3b-kde4/Makefile
index 364efab790fd..519c3c33cd4f 100644
--- a/sysutils/k3b-kde4/Makefile
+++ b/sysutils/k3b-kde4/Makefile
@@ -7,7 +7,7 @@
PORTNAME= k3b
PORTVERSION= 2.0.2
-PORTREVISION= 5
+PORTREVISION= 6
CATEGORIES= sysutils multimedia kde
MASTER_SITES= SF/${PORTNAME}/${PORTNAME}/${PORTVERSION}
diff --git a/sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp b/sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp
index 1ae9c2dabb00..82f06a8d9490 100644
--- a/sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp
+++ b/sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp
@@ -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,
+@@ -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>
+
+-#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;
++}
- struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
+- 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();
-@@ -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;
+-
+- if( needToClose )
+- m_device->close();
+- m_device->usageUnlock();
+-
+- return -1;
++ kWarning() << "(K3b::Device::ScsiCommand) transport getting sense data failed: " << ret;
++ return 1;
+ }
+
+- 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();
+-
+- 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";
+
++ ret = sense_to_err(ccb.csio.sense_data);
++ if( ret == 0 )
++ ret = 1;
++ kDebug() << "(K3b::Device::ScsiCommand) transport failed: " << ret;
+ return ret;
+ }