File indexing completed on 2024-04-14 04:44:46

0001 /*
0002     SPDX-FileCopyrightText: 2006 Mark Davies <mark@mcs.vuw.ac.nz>
0003     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 
0009 #include "k3bscsicommand.h"
0010 #include "k3bdevice.h"
0011 
0012 #include <QDebug>
0013 
0014 #include <sys/ioctl.h>
0015 #include <sys/scsiio.h>
0016 // #include <sys/cdio.h>
0017 // #include <sys/dkio.h>
0018 
0019 #include <unistd.h>
0020 #include <sys/types.h>
0021 
0022 
0023 class K3b::Device::ScsiCommand::Private
0024 {
0025 public:
0026     struct scsireq cmd;
0027 };
0028 
0029 
0030 void K3b::Device::ScsiCommand::clear()
0031 {
0032     ::memset( &d->cmd, 0, sizeof(struct scsireq ) );
0033 }
0034 
0035 
0036 unsigned char& K3b::Device::ScsiCommand::operator[]( size_t i )
0037 {
0038     if( d->cmd.cmdlen < i+1 )
0039         d->cmd.cmdlen = i+1;
0040     return d->cmd.cmd[i];
0041 }
0042 
0043 
0044 int K3b::Device::ScsiCommand::transport( TransportDirection dir,
0045                                          void* data,
0046                                          size_t len )
0047 {
0048     bool needToClose = false;
0049     int deviceHandle = -1;
0050     if( m_device ) {
0051         m_device->usageLock();
0052         if( !m_device->isOpen() ) {
0053             needToClose = true;
0054         }
0055         m_device->open( dir == TR_DIR_WRITE );
0056         deviceHandle = m_device->handle();
0057     }
0058 
0059     if( deviceHandle == -1 ) {
0060         if ( m_device ) {
0061             m_device->usageUnlock();
0062         }
0063 
0064         return -1;
0065     }
0066 
0067     d->cmd.timeout = 10000;
0068     d->cmd.databuf = (caddr_t) data;
0069     d->cmd.datalen = len;
0070     //  d->cmd.datalen_used = len;
0071     d->cmd.senselen = SENSEBUFLEN;
0072     switch (dir)
0073     {
0074     case TR_DIR_READ:
0075         d->cmd.flags = SCCMD_READ;
0076         break;
0077     case TR_DIR_WRITE:
0078         d->cmd.flags = SCCMD_WRITE;
0079         break;
0080     default:
0081         d->cmd.flags = SCCMD_READ;
0082         break;
0083     }
0084 
0085     int i = ::ioctl( deviceHandle, SCIOCCOMMAND, &d->cmd );
0086 
0087     if ( m_device ) {
0088         if( needToClose )
0089             m_device->close();
0090         m_device->usageUnlock();
0091     }
0092 
0093     if( i || (d->cmd.retsts != SCCMD_OK)) {
0094         debugError( d->cmd.cmd[0],
0095                     d->cmd.retsts,
0096                     d->cmd.sense[2],
0097                     d->cmd.sense[12],
0098                     d->cmd.sense[13] );
0099 
0100         return 1;
0101     }
0102     else
0103         return 0;
0104 }