--- Begin Message ---
Package: k3b
Version: 2.0.2-3
Severity: serious
Tags: patch
User: debian-...@lists.debian.org
Usertags: kfreebsd
k3b FTBFS on kfreebsd-* since the CAM API transition:
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:175:33:
error: 'struct scsi_sense_data' has no member named 'flags'
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:176:33:
error: 'struct scsi_sense_data' has no member named 'add_sense_code'
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:177:33:
error: 'struct scsi_sense_data' has no member named 'add_sense_code_qual'
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:198:25:
error: 'struct scsi_sense_data' has no member named 'flags'
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:199:25:
error: 'struct scsi_sense_data' has no member named 'add_sense_code'
/build/buildd-k3b_2.0.2-3+b1-kfreebsd-amd64-sxsDco/k3b-2.0.2/libk3bdevice/k3bscsicommand_bsd.cpp:200:25:
error: 'struct scsi_sense_data' has no member named 'add_sense_code_qual'
A patch to fix this can be obtained from FreeBSD ports collection, see:
http://www.freebsd.org/cgi/cvsweb.cgi/~checkout~/ports/sysutils/k3b-kde4/files/patch-libk3bdevice-k3bscsicommandbsd.cpp?rev=1.2;content-type=text%2Fplain
(also attached)
-- System Information:
Debian Release: 6.0.4
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: kfreebsd-amd64 (x86_64)
Kernel: kFreeBSD 8.1-1-amd64
Locale: LANG=ca_AD.UTF-8, LC_CTYPE=ca_AD.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diff --git a/libk3bdevice/k3bscsicommand_bsd.cpp b/libk3bdevice/k3bscsicommand_bsd.cpp
index ce6508e..63a8fd5 100644
--- ./libk3bdevice/k3bscsicommand_bsd.cpp
+++ ./libk3bdevice/k3bscsicommand_bsd.cpp
@@ -1,6 +1,7 @@
/*
*
* Copyright (C) 2003-2009 Sebastian Trueg <tr...@k3b.org>
+ * Copyright (C) 2011 Andriy Gapon <a...@freebsd.org>
*
* This file is part of the K3b project.
* Copyright (C) 1998-2009 Sebastian Trueg <tr...@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;
+}
- 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 );
+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 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;
+ 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;
}
-
- 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 );
-
- 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 );
-
- 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 );
-
- 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;
}
--- End Message ---