View | Details | Raw Unified | Return to bug 166302
Collapse All | Expand All

(-)./Makefile (-2 / +2 lines)
Lines 7-13 Link Here
7
7
8
PORTNAME=	k3b
8
PORTNAME=	k3b
9
PORTVERSION=	1.0.5
9
PORTVERSION=	1.0.5
10
PORTREVISION=	14
10
PORTREVISION=	15
11
CATEGORIES=	sysutils multimedia kde
11
CATEGORIES=	sysutils multimedia kde
12
MASTER_SITES=	SF
12
MASTER_SITES=	SF
13
13
Lines 58-64 Link Here
58
.include <bsd.port.pre.mk>
58
.include <bsd.port.pre.mk>
59
59
60
.if ${OSVERSION} >= 900044
60
.if ${OSVERSION} >= 900044
61
BROKEN=		does not compile on FreeBSD 9.X
61
EXTRA_PATCHES+=		${FILESDIR}/extra-patch-libk3bdevice-k3bscsicommandbsd.cpp
62
.endif
62
.endif
63
63
64
PKGMESSAGE=	${PKGDIR}/pkg-message-7
64
PKGMESSAGE=	${PKGDIR}/pkg-message-7
(-)./files/extra-patch-libk3bdevice-k3bscsicommandbsd.cpp (+286 lines)
Line 0 Link Here
1
--- libk3bdevice/k3bscsicommand_bsd.cpp.orig	2012-03-22 03:26:44.000000000 +0600
2
+++ libk3bdevice/k3bscsicommand_bsd.cpp	2012-03-22 03:11:30.000000000 +0600
3
@@ -17,6 +17,7 @@
4
 #include "k3bdevice.h"
5
 
6
 #include <k3bdebug.h>
7
+#include <kdebug.h>
8
 
9
 #include <stdio.h>
10
 #include <errno.h>
11
@@ -24,41 +25,44 @@
12
 #include <cam/scsi/scsi_message.h>
13
 #include <cam/scsi/scsi_pass.h>
14
 
15
-#define ERRCODE(s)	((((s)[2]&0x0F)<<16)|((s)[12]<<8)|((s)[13]))
16
-#define EMEDIUMTYPE	EINVAL
17
-#define	ENOMEDIUM	ENODEV
18
-#define CREAM_ON_ERRNO(s)	do {			\
19
-    switch ((s)[12])					\
20
-    {	case 0x04:	errno=EAGAIN;	break;		\
21
-	case 0x20:	errno=ENODEV;	break;		\
22
-	case 0x21:	if ((s)[13]==0)	errno=ENOSPC;	\
23
-			else		errno=EINVAL;	\
24
-			break;				\
25
-	case 0x30:	errno=EMEDIUMTYPE;  break;	\
26
-	case 0x3A:	errno=ENOMEDIUM;    break;	\
27
-    }							\
28
-} while(0)
29
+namespace /*anonymous*/
30
+{
31
+    inline int sense_to_err( const struct scsi_sense_data& s )
32
+    {
33
+        int errorCode, senseKey, addSenseCode, addSenseCodeQual;
34
+        scsi_extract_sense( (struct scsi_sense_data*) &s, &errorCode,
35
+                            &senseKey, &addSenseCode, &addSenseCodeQual );
36
+        return (errorCode << 24) | (senseKey << 16) |
37
+              (addSenseCode << 8) | addSenseCodeQual;
38
+    }
39
+}
40
 
41
 
42
 
43
 class K3bDevice::ScsiCommand::Private
44
 {
45
+	typedef union ccb CCB;
46
 public:
47
-  union ccb ccb;
48
+	    Private();
49
+	    int transport( const Device* device, TransportDirection dir, void* data, size_t len );
50
+	    unsigned char& operator[]( size_t i );
51
+	    void clear();
52
+	    const CCB& get_ccb() { return ccb; }
53
+	
54
+		private:
55
+		    CCB ccb;
56
 };
57
 
58
 
59
 void K3bDevice::ScsiCommand::clear()
60
 {
61
-  memset (&d->ccb,0,sizeof(ccb));
62
+  d->clear();
63
 }
64
 
65
 
66
 unsigned char& K3bDevice::ScsiCommand::operator[]( size_t i )
67
 {
68
-  if( d->ccb.csio.cdb_len < i+1 )
69
-    d->ccb.csio.cdb_len = i+1;
70
-  return d->ccb.csio.cdb_io.cdb_bytes[i];
71
+  return (*d)[i];
72
 }
73
 
74
 int K3bDevice::ScsiCommand::transport( TransportDirection dir,
75
@@ -79,130 +83,103 @@
76
       m_device->usageUnlock();
77
       return -1;
78
   }
79
-  d->ccb.ccb_h.path_id    = m_device->handle()->path_id;
80
-  d->ccb.ccb_h.target_id  = m_device->handle()->target_id;
81
-  d->ccb.ccb_h.target_lun = m_device->handle()->target_lun;
82
-
83
-  k3bDebug() << "(K3bDevice::ScsiCommand) transport command " << QString::number((int)d->ccb.csio.cdb_io.cdb_bytes[0], 16) << ", length: " << (int)d->ccb.csio.cdb_len << endl;
84
-  int ret=0;
85
-  int direction = CAM_DEV_QFRZDIS;
86
-  if (!len)
87
-    direction |= CAM_DIR_NONE;
88
-  else
89
-    direction |= (dir & TR_DIR_READ)?CAM_DIR_IN : CAM_DIR_OUT;
90
-  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);
91
-  unsigned char * sense = (unsigned char *)&d->ccb.csio.sense_data;
92
 
93
-  ret = cam_send_ccb(m_device->handle(), &d->ccb);
94
+    int ret = d->transport( m_device, dir, data, len );
95
+    if( ret != 0 ) {
96
+	        const struct scsi_sense_data& s = d->get_ccb().csio.sense_data;
97
+	        int errorCode, senseKey, addSenseCode, addSenseCodeQual;
98
+	        scsi_extract_sense( (struct scsi_sense_data*) &s, &errorCode, &senseKey,
99
+			                            &addSenseCode, &addSenseCodeQual );
100
+	        debugError( d->get_ccb().csio.cdb_io.cdb_bytes[0],
101
+			                    errorCode,
102
+			                    senseKey,
103
+			                    addSenseCode,
104
+			                    addSenseCodeQual );
105
+	    }
106
+
107
+    if( needToClose )
108
+	        m_device->close();
109
+    m_device->usageUnlock();
110
 
111
-  if (ret < 0) {
112
-      k3bDebug() << "(K3bDevice::ScsiCommand) transport failed: " << ret << endl;
113
+    return ret;
114
+}
115
 
116
-      if( needToClose )
117
-          m_device->close();
118
+K3bDevice::ScsiCommand::Private::Private()
119
+	{
120
+		    clear();
121
+		}
122
 
123
-      m_device->usageUnlock();
124
+void K3bDevice::ScsiCommand::Private::clear()
125
+	{
126
+		    memset( &ccb, 0, sizeof(ccb) );
127
+		}
128
 
129
-      struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
130
-      debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
131
-		  senset->error_code & SSD_ERRCODE,
132
-		  senset->flags & SSD_KEY,
133
-		  senset->add_sense_code,
134
-		  senset->add_sense_code_qual );
135
-
136
-      int result = (((senset->error_code & SSD_ERRCODE)<<24) & 0xF000 |
137
-                    ((senset->flags & SSD_KEY)<<16)          & 0x0F00 |
138
-                    (senset->add_sense_code<<8)              & 0x00F0 |
139
-                    (senset->add_sense_code_qual)            & 0x000F );
140
+      unsigned char& K3bDevice::ScsiCommand::Private::operator[]( size_t i )
141
+	{
142
+	    if( ccb.csio.cdb_len < i + 1 )
143
+	        ccb.csio.cdb_len = i + 1;
144
+	    return ccb.csio.cdb_io.cdb_bytes[i];
145
+	}
146
 
147
-      return result ? result : ret;
148
+      int K3bDevice::ScsiCommand::Private::transport( const Device* device, TransportDirection dir, void* data, size_t len )
149
+	{
150
+		          ccb.ccb_h.path_id    = device->handle()->path_id;
151
+		          ccb.ccb_h.target_id  = device->handle()->target_id;
152
+		          ccb.ccb_h.target_lun = device->handle()->target_lun;
153
+
154
+    k3bDebug() << "(K3bDevice::ScsiCommand) transport command " << commandString(ccb.csio.cdb_io.cdb_bytes[0])
155
+             << " (" << QString::number((int)ccb.csio.cdb_io.cdb_bytes[0], 16) << "), length: " << (int)ccb.csio.cdb_len;
156
+    int direction = CAM_DEV_QFRZDIS;
157
+    if (!len)
158
+	        direction |= CAM_DIR_NONE;
159
+    else
160
+	        direction |= (dir & TR_DIR_READ) ? CAM_DIR_IN : CAM_DIR_OUT;
161
+
162
+	    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 );
163
+    int ret = cam_send_ccb( device->handle(), &ccb );
164
+    if( ret < 0 ) {
165
+	        kdError() << "(K3bDevice::ScsiCommand) transport cam_send_ccb failed: ret = " << ret
166
+		                 << ", errno = " << errno << ", cam_errbuf = " << cam_errbuf;
167
+	        return 1;
168
   }
169
 
170
-  else if ((d->ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
171
-      if( needToClose )
172
-          m_device->close();
173
-      m_device->usageUnlock();
174
+        else if( (ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP ) {
175
+	            k3bDebug() << "(K3bDevice::ScsiCommand) transport succeeded";
176
       return 0;
177
   }
178
 
179
-  errno = EIO;
180
-  // FreeBSD 5-CURRENT since 2003-08-24, including 5.2 fails to
181
-  // pull sense data automatically, at least for ATAPI transport,
182
-  // so I reach for it myself...
183
-  if ((d->ccb.csio.scsi_status==SCSI_STATUS_CHECK_COND) &&
184
-      !(d->ccb.ccb_h.status&CAM_AUTOSNS_VALID))
185
-    {
186
-      u_int8_t  _sense[18];
187
-      u_int32_t resid=d->ccb.csio.resid;
188
-
189
-      memset(_sense,0,sizeof(_sense));
190
-
191
-      operator[](0)      = 0x03;	// REQUEST SENSE
192
-      d->ccb.csio.cdb_io.cdb_bytes[4] = sizeof(_sense);
193
-      d->ccb.csio.cdb_len   = 6;
194
-      d->ccb.csio.ccb_h.flags |= CAM_DIR_IN|CAM_DIS_AUTOSENSE;
195
-      d->ccb.csio.data_ptr  = _sense;
196
-      d->ccb.csio.dxfer_len = sizeof(_sense);
197
-      d->ccb.csio.sense_len = 0;
198
-
199
-      ret = cam_send_ccb(m_device->handle(), &d->ccb);
200
+    k3bDebug() << "(K3bDevice::ScsiCommand) transport command failed: scsi_status = " << QString::number(ccb.csio.scsi_status, 16);
201
 
202
-      d->ccb.csio.resid = resid;
203
-      if (ret<0)
204
+    if( ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND &&
205
+		        !(ccb.ccb_h.status & CAM_AUTOSNS_VALID) &&
206
+		        ccb.csio.cdb_io.cdb_bytes[0] != MMC_REQUEST_SENSE )
207
+	    {
208
+		        k3bDebug() << "(K3bDevice::ScsiCommand) transport requesting sense data";
209
+		 
210
+        struct scsi_sense_data sense;
211
+        ScsiCommand::Private cmd;
212
+        cmd[0] = MMC_REQUEST_SENSE;
213
+        cmd[4] = SSD_MIN_SIZE;
214
+        cmd[5] = 0; // Necessary to set the proper command length
215
+
216
+	        memset( &sense, 0, sizeof(sense) );
217
+	        ret = cmd.transport( device, TR_DIR_READ, &sense, SSD_MIN_SIZE );
218
+	        if( ret < 0 )
219
 	{
220
-	  k3bDebug() << "(K3bDevice::ScsiCommand) transport failed (2): " << ret << endl;
221
-	  ret = -1;
222
-	  struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
223
-	  debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
224
-		      senset->error_code & SSD_ERRCODE,
225
-		      senset->flags & SSD_KEY,
226
-		      senset->add_sense_code,
227
-		      senset->add_sense_code_qual );
228
-
229
-	  if( needToClose )
230
-	    m_device->close();
231
-          m_device->usageUnlock();
232
-
233
-	  return -1;
234
+            kdWarning() << "(K3bDevice::ScsiCommand) transport getting sense data failed: " << ret;
235
+            return 1;
236
 	}
237
-      if ((d->ccb.ccb_h.status&CAM_STATUS_MASK) != CAM_REQ_CMP)
238
-	{
239
-	  k3bDebug() << "(K3bDevice::ScsiCommand) transport failed (3): " << ret << endl;
240
-	  errno=EIO,-1;
241
-	  ret = -1;
242
-	  struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
243
-	  debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
244
-		      senset->error_code & SSD_ERRCODE,
245
-		      senset->flags & SSD_KEY,
246
-		      senset->add_sense_code,
247
-		      senset->add_sense_code_qual );
248
-
249
-	  if( needToClose )
250
-	    m_device->close();
251
-          m_device->usageUnlock();
252
 
253
-	  return -1;
254
-	}
255
-
256
-      memcpy(sense,_sense,sizeof(_sense));
257
+        ccb.csio.sense_data = sense;
258
+        ccb.ccb_h.status |= CAM_AUTOSNS_VALID;
259
     }
260
 
261
-  ret = ERRCODE(sense);
262
-  k3bDebug() << "(K3bDevice::ScsiCommand) transport failed (4): " << ret << endl;
263
-  if (ret == 0)
264
-    ret = -1;
265
-  else
266
-    CREAM_ON_ERRNO(((unsigned char *)&d->ccb.csio.sense_data));
267
-  struct scsi_sense_data* senset = (struct scsi_sense_data*)sense;
268
-  debugError( d->ccb.csio.cdb_io.cdb_bytes[0],
269
-	      senset->error_code & SSD_ERRCODE,
270
-	      senset->flags & SSD_KEY,
271
-	      senset->add_sense_code,
272
-	      senset->add_sense_code_qual );
273
-
274
-  if( needToClose )
275
-    m_device->close();
276
-  m_device->usageUnlock();
277
-
278
+    if( !(ccb.ccb_h.status & CAM_AUTOSNS_VALID) )
279
+	        k3bDebug() << "(K3bDevice::ScsiCommand) sense data is not available";
280
+ 
281
+    ret = sense_to_err(ccb.csio.sense_data);
282
+    if( ret == 0 )
283
+	        ret = 1;
284
+    k3bDebug() << "(K3bDevice::ScsiCommand) transport failed: " << ret;
285
   return ret;
286
 }

Return to bug 166302