xref: /haiku/src/add-ons/kernel/generic/scsi_periph/scsi_periph_int.h (revision d8ffdea39e122821c22bb610e965a2823bbd4480)
1 /*
2  * Copyright 2004-2013, Haiku, Inc. All Rights Reserved.
3  * Copyright 2002, Thomas Kurschel. All rights reserved.
4  * Distributed under the terms of the MIT License.
5  */
6 #ifndef __SCSI_PERIPH_INT_H__
7 #define __SCSI_PERIPH_INT_H__
8 
9 
10 #include <stddef.h>
11 
12 #include <scsi_periph.h>
13 #include <device_manager.h>
14 
15 #include "IORequest.h"
16 #include "wrapper.h"
17 
18 
19 enum trim_command {
20 	TRIM_NONE,			// TRIM operation is disabled for this device
21 	TRIM_UNMAP,			// UNMAP command wil be used
22 	TRIM_WRITESAME10,	// WRITE SAME (10) with UNMAP bit enabled will be used
23 	TRIM_WRITESAME16	// WRITE SAME (16) with UNMAP bit enabled will be used
24 };
25 
26 
27 typedef struct scsi_periph_device_info {
28 	struct scsi_periph_handle_info *handles;
29 
30 	::scsi_device scsi_device;
31 	scsi_device_interface *scsi;
32 	periph_device_cookie periph_device;
33 	device_node *node;
34 
35 	bool removal_requested;
36 
37 	bool removable;			// true, if device is removable
38 
39 	enum trim_command unmap_command;	// command to be used to discard free blocks
40 	uint32 max_unmap_lba_count;			// max. number of LBAs in one command
41 	uint32 max_unmap_descriptor_count;	// max. number of ranges in one command
42 
43 	uint32 block_size;
44 	int32 preferred_ccb_size;
45 	int32 rw10_enabled;		// 10 byte r/w commands supported; access must be atomic
46 	int32 next_tag_action;	// queuing flag for next r/w command; access must be atomic
47 
48 	struct mutex mutex;
49 	int std_timeout;
50 
51 	scsi_periph_callbacks *callbacks;
52 } scsi_periph_device_info;
53 
54 typedef struct scsi_periph_handle_info {
55 	scsi_periph_device_info *device;
56 	struct scsi_periph_handle_info *next, *prev;
57 
58 	int pending_error;		// error to be reported on all accesses
59 							// (used to block access after medium change until
60 							//  B_GET_MEDIA_STATUS is called)
61 	periph_handle_cookie periph_handle;
62 } scsi_periph_handle_info;
63 
64 extern device_manager_info *gDeviceManager;
65 
66 
67 // removable.c
68 
69 void periph_media_changed(scsi_periph_device_info *device, scsi_ccb *ccb);
70 void periph_media_changed_public(scsi_periph_device_info *device);
71 status_t periph_get_media_status(scsi_periph_handle_info *handle);
72 err_res periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request,
73 	bool start, bool with_LoEj);
74 
75 
76 // error_handling.c
77 
78 err_res periph_check_error(scsi_periph_device_info *device, scsi_ccb *request);
79 
80 
81 // handle.c
82 
83 status_t periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle,
84 	scsi_periph_handle_info **res_handle);
85 status_t periph_handle_close(scsi_periph_handle_info *handle);
86 status_t periph_handle_free(scsi_periph_handle_info *handle);
87 
88 
89 // block.c
90 
91 status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
92 status_t periph_trim_device(scsi_periph_device_info *device, scsi_ccb *request,
93 	scsi_block_range* ranges, uint32 rangeCount, uint64* trimmedBlocks);
94 
95 
96 // device.c
97 
98 status_t periph_register_device(periph_device_cookie periph_device,
99 	scsi_periph_callbacks *callbacks, scsi_device scsi_device,
100 	scsi_device_interface *scsi, device_node *node, bool removable,
101 	int preferredCcbSize, scsi_periph_device *driver);
102 status_t periph_unregister_device(scsi_periph_device_info *driver);
103 char *periph_compose_device_name(device_node *device_node, const char *prefix);
104 
105 
106 // io.c
107 
108 status_t periph_read_write(scsi_periph_device_info *device, scsi_ccb *request,
109 	uint64 offset, size_t numBlocks, physical_entry* vecs, size_t vecCount,
110 	bool isWrite, size_t* _bytesTransferred);
111 status_t periph_io(scsi_periph_device_info* device, io_operation* operation,
112 	size_t *_bytesTransferred);
113 status_t periph_ioctl(scsi_periph_handle_info *handle, int op,
114 	void *buf, size_t len);
115 void periph_sync_queue_daemon(void *arg, int iteration);
116 status_t vpd_page_get(scsi_periph_device_info *device, scsi_ccb* request,
117 	uint8 page, void* data, uint16 length);
118 
119 
120 // scsi_periph.c
121 
122 status_t periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request);
123 status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb,
124 	uchar cdb_len, void *data, size_t data_len, int ccb_flags);
125 
126 
127 // sync.c
128 
129 err_res periph_synchronize_cache(scsi_periph_device_info *device,
130 	scsi_ccb *request);
131 
132 #endif	/* __SCSI_PERIPH_INT_H__ */
133