I have a USB device (actually, a digital camera) that talks the MSC protocol, i.e. it appears as a disk device and can be talked to with SCSI commands. When it's connected to a Mac, the IOBlockStorageDriver
takes over and mounts the volume.
Now, my goal is to prevent this from happening, in hopes that I can then talk to the device thru the SCSI interface functions for SCSITaskDeviceInterface
, provided in <IOKit/scsi/SCSITaskLib.h>
.
Is that possible? The SCSI Architecture Model Device Interface Guide states that the SCSITaskDeviceInterface
is only available for types other than $00, $05, $07 and $0E (the MSC device is type 00), but I wonder if that's only because these types are taken over by the Mass Storage driver and therefore are not available. But if I prevent the Mass Storage driver to take over, will these types, such as 00, become available via SCSITaskDeviceInterface
?
If that's possible, what must the kext code do to achieve this? E.g, which class should it subclass and which functions must it implement so that it prevents the mass storage driver from taking over while keeping the device visibile as a SCSI device in the io registry?
If that's not possible, could I then instead use the kext to provide a way to offer SCSI-cmd passthrough somehow? I would like to be able to send custom CDBs to this kext from userland, and it should then route them through the SCSI layer to the USB device. Is that possible? Assuming the kext has received a CDB string, how would it locate the SCSI functions for passing the data onward to the USB layer?
I've so far based my unsuccessful tests on Apple's VendorSpecificType00 sample project, which shows how to inject a kext that adds handling custom properties for a SCSI device.
For now, let's ignore upcoming kext deprecations by recent macOS versions (I want to get this working on High Sierra first).