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:
parent
46d560e64b
commit
555cbea998
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=290934
@ -7,7 +7,7 @@
|
||||
|
||||
PORTNAME= k3b
|
||||
PORTVERSION= 2.0.2
|
||||
PORTREVISION= 5
|
||||
PORTREVISION= 6
|
||||
CATEGORIES= sysutils multimedia kde
|
||||
MASTER_SITES= SF/${PORTNAME}/${PORTNAME}/${PORTVERSION}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user