SCSI: Use an object_cache for the CCB pool.

Same as for the scatter/gather pool. This also changes CCBs
to use condition variables instead of semaphores for completion,
which means they're now C++-only. A few C files still include
<SCSI.h>, but none use CCBs directly, so this works out fine.

A quick check with a compile benchmark didn't show a performance regression.
This commit is contained in:
Augustin Cavalier
2024-11-05 13:43:48 -05:00
parent 67c520afb0
commit 7746364088
7 changed files with 56 additions and 88 deletions
+13 -13
View File
@@ -94,17 +94,18 @@
#include <KernelExport.h>
#ifdef _KERNEL_MODE
#include <condition_variable.h>
#include <device_manager.h>
#endif
#define SCSI_MAX_CDB_SIZE 16 // max size of cdb
#define SCSI_MAX_SENSE_SIZE 64 // max size of sense data
// bus/device handle
typedef struct scsi_bus_info *scsi_bus;
typedef struct scsi_device_info *scsi_device;
#if defined(__cplusplus) && defined(_KERNEL_MODE)
// structure of one scsi i/o CCB (command control block)
typedef struct scsi_ccb {
struct scsi_ccb *next, *prev; // internal
@@ -117,11 +118,10 @@ typedef struct scsi_ccb {
uchar target_lun; // Target LUN number
uint32 flags; // Flags for operation of the subsystem
// released once after asynchronous execution of request;
// initialised by alloc_ccb, can be replaced for action but
// must be restored before returning via free_ccb
sem_id completion_sem;
// notified after asynchronous execution of request
ConditionVariable completion_cond;
#define SCSI_MAX_CDB_SIZE 16
uint8 cdb[SCSI_MAX_CDB_SIZE]; // command data block
uchar cdb_length; // length of command in bytes
int64 sort; // value of command to sort on (<0 means n/a)
@@ -134,6 +134,7 @@ typedef struct scsi_ccb {
int32 data_resid; // data transfer residual length: 2's comp
void *io_operation;
#define SCSI_MAX_SENSE_SIZE 64
uchar sense[SCSI_MAX_SENSE_SIZE]; // autosense data
uchar sense_resid; // autosense resid length: 2's comp
@@ -154,6 +155,9 @@ typedef struct scsi_ccb {
uint16 orig_sg_count;
uint32 orig_data_length;
} scsi_ccb;
#else
typedef struct scsi_ccb scsi_ccb;
#endif
// Defines for the subsystem status field
@@ -291,15 +295,11 @@ typedef struct {
typedef struct scsi_device_interface {
driver_module_info info;
// get CCB
// warning: if pool of CCBs is exhausted, this call is delayed until a
// CCB is freed, so don't try to allocate more then one CCB at once!
scsi_ccb *(*alloc_ccb)(scsi_device device);
// free CCB
void (*free_ccb)(scsi_ccb *ccb);
// execute command asynchronously
// when it's finished, the semaphore of the ccb is released
// when it's finished, the condvar of the ccb is released
// you must provide a S/G list if data_len != 0
void (*async_io)(scsi_ccb *ccb);
// execute command synchronously