limitations of UserSendCDB in SCSIPeripheralsDriverKit?

I've made a dext and a user client that overrides IOUserSCSIPeripheralDeviceType00, with the object of writing device firmware to the driver. I can gain and relinquish exclusive access to the device, I can call UserReportMediumBlockSize and get back a sensible answer (512). I can build command parameters with the INQUIRY macro from IOUserSCSIPeripheralDeviceHelper.h and send that command successfully using UserSendCB, and I receive sensible-looking Inquiry data from the device.

However, what I really want to do is send a WriteBuffer command (opcode 0x3B), and that doesn't work. I have yet to put a bus analyzer on it, but I don't think the command goes out on the bus - there's no valid sense data, and the error returned is 0xe00002bc, or kIOReturnError, which isn't helpful.

This is the code I have which doesn't work.

kern_return_t driver::writeChunk(const char * buf, size_t atOffset, size_t length, bool lastOne)
{
    DebugMsg("writeChunk %p at %ld for %ld", buf, atOffset, length);
    SCSIType00OutParameters outParameters;
    SCSIType00InParameters response;
    
    memset(&outParameters, 0, sizeof(outParameters));
    memset(&response, 0, sizeof(response));
    
    SetCommandCDB(&outParameters.fCommandDescriptorBlock,
                  0x3B, // byte 0, opcode WriteBuffer command
                  lastOne ?   0x0E : 0x0F, // byte 1 mode: E=save deferred, F = download and defer save
                  0, // byte 2 bufferID
                  (atOffset >> 16), // byte 3
                  (atOffset >> 8),         // byte 4
                  atOffset,         // byte 5
                  (length >> 16),    // byte 6
                  (length >> 8),           // byte 7
                  length,              // byte 8
                  0, // control, byte 9
                  0, 0, 0, 0, 0, 0); // bytes 10..15
    
    outParameters.fLogicalUnitNumber = 0;
    outParameters.fBufferDirection = kIOMemoryDirectionOut;
    outParameters.fDataTransferDirection = kSCSIDataTransfer_FromInitiatorToTarget;

    outParameters.fTimeoutDuration = 1000; // milliseconds
    outParameters.fRequestedByteCountOfTransfer = length;
    outParameters.fDataBufferAddr = reinterpret_cast<uint64_t>(buf);
    
    uint8_t senseBuffer[255] = {0};
    outParameters.fSenseBufferAddr = reinterpret_cast<uint64_t>(senseBuffer);
    outParameters.fSenseLengthRequested = sizeof(senseBuffer);
    
    kern_return_t retVal = UserSendCDB(outParameters, &response);
                  
    return retVal;
}

The error returned is 0xe00002bc, or kIOReturnError, which isn't helpful.

So, kIOReturnError is the "default" error return value for UserSendCDB, which basically means it will return that for any "high level" check that doesn't have a more specific error specifically assigned.

*Notably, attempting to send a command that requires exclusive access will return "kIOReturnNotPrivileged".

Looking at your code, I think** the issue here is actually this:

**It’s possible there are other issues, but this will definitely create the failure you’re seeing.

uint8_t senseBuffer[255] = {0};
outParameters.fSenseBufferAddr = reinterpret_cast<uint64_t>(senseBuffer);
outParameters.fSenseLengthRequested = sizeof(senseBuffer);

There is an early size check in UserSendCDB which checks the buffer size against the size of the kernel sense structure and fails if the size is greater than that structure (currently, 20 bytes).

Looking at our code, we either use this:

outParameters.fSenseLengthRequested = sizeof ( SCSI_Sense_Data );

...or zero.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you once again Kevin! I filed a bug against the documentation: FB20379178

Now that I'm using

uint8_t senseBuffer[20] = {0};

I run into a new problem. I started a new thread on it: https://developer.apple.com/forums/thread/802099

Thank you once again Kevin! I filed a bug against the documentation: FB20379178

Perfect, thank you!

I run into a new problem.

Progress!

I started a new thread on it: https://developer.apple.com/forums/thread/802099

Thank you, and see my reply there.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

limitations of UserSendCDB in SCSIPeripheralsDriverKit?
 
 
Q