2 ** Copyright 2002/03, Thomas Kurschel. All rights reserved.
3 ** Distributed under the terms of the OpenBeOS License.
7 Part of Open SCSI bus manager
11 As allocation of ccb can be on the paging path we must use a
15 #include "scsi_internal.h"
19 // ccb are relatively large, so don't make it too small to not waste memory
20 #define CCB_CHUNK_SIZE 16*1024
22 // maximum number of CCBs - probably, we want to make that editable
23 // it must be at least 1 for normal use and 1 for stand-by autosense request
24 #define CCB_NUM_MAX 128
28 scsi_alloc_ccb(scsi_device_info
*device
)
34 ccb
= (scsi_ccb
*)locked_pool
->alloc(device
->bus
->ccb_pool
);
35 ccb
->state
= SCSI_STATE_FINISHED
;
37 ccb
->target_id
= device
->target_id
;
38 ccb
->target_lun
= device
->target_lun
;
40 // reset some very important fields
41 // TODO: should we better omit that to find bugs easier?
43 ccb
->io_operation
= NULL
;
46 SHOW_FLOW(3, "path=%d", ccb
->path_id
);
53 scsi_free_ccb(scsi_ccb
*ccb
)
57 if (ccb
->state
!= SCSI_STATE_FINISHED
)
58 panic("Tried to free ccb that's still in use (state %d)\n", ccb
->state
);
60 ccb
->state
= SCSI_STATE_FREE
;
62 locked_pool
->free(ccb
->bus
->ccb_pool
, ccb
);
67 ccb_low_alloc_hook(void *block
, void *arg
)
69 scsi_ccb
*ccb
= (scsi_ccb
*)block
;
70 scsi_bus_info
*bus
= (scsi_bus_info
*)arg
;
74 ccb
->path_id
= bus
->path_id
;
75 ccb
->state
= SCSI_STATE_FREE
;
77 if ((res
= ccb
->completion_sem
= create_sem(0, "ccb_sem")) < 0)
85 ccb_low_free_hook(void *block
, void *arg
)
87 scsi_ccb
*ccb
= (scsi_ccb
*)block
;
89 delete_sem(ccb
->completion_sem
);
94 scsi_init_ccb_alloc(scsi_bus_info
*bus
)
96 // initially, we want no CCB allocated as the path_id of
97 // the bus is not ready yet so the CCB cannot be initialized
99 bus
->ccb_pool
= locked_pool
->create(sizeof(scsi_ccb
), sizeof(uint32
) - 1, 0,
100 CCB_CHUNK_SIZE
, CCB_NUM_MAX
, 0, "scsi_ccb_pool", B_CONTIGUOUS
,
101 ccb_low_alloc_hook
, ccb_low_free_hook
, bus
);
103 if (bus
->ccb_pool
== NULL
)
111 scsi_uninit_ccb_alloc(scsi_bus_info
*bus
)
113 locked_pool
->destroy(bus
->ccb_pool
);