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
19enum 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
27typedef 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	uint32 physical_block_size;
45	int32 preferred_ccb_size;
46	int32 rw10_enabled;		// 10 byte r/w commands supported; access must be atomic
47	int32 next_tag_action;	// queuing flag for next r/w command; access must be atomic
48
49	struct mutex mutex;
50	int std_timeout;
51
52	scsi_periph_callbacks *callbacks;
53} scsi_periph_device_info;
54
55typedef struct scsi_periph_handle_info {
56	scsi_periph_device_info *device;
57	struct scsi_periph_handle_info *next, *prev;
58
59	int pending_error;		// error to be reported on all accesses
60							// (used to block access after medium change until
61							//  B_GET_MEDIA_STATUS is called)
62	periph_handle_cookie periph_handle;
63} scsi_periph_handle_info;
64
65extern device_manager_info *gDeviceManager;
66
67
68// removable.c
69
70void periph_media_changed(scsi_periph_device_info *device, scsi_ccb *ccb);
71void periph_media_changed_public(scsi_periph_device_info *device);
72status_t periph_get_media_status(scsi_periph_handle_info *handle);
73err_res periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request,
74	bool start, bool with_LoEj);
75
76
77// error_handling.c
78
79err_res periph_check_error(scsi_periph_device_info *device, scsi_ccb *request);
80
81
82// handle.c
83
84status_t periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle,
85	scsi_periph_handle_info **res_handle);
86status_t periph_handle_close(scsi_periph_handle_info *handle);
87status_t periph_handle_free(scsi_periph_handle_info *handle);
88
89
90// block.c
91
92status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
93status_t periph_trim_device(scsi_periph_device_info *device, scsi_ccb *request,
94	scsi_block_range* ranges, uint32 rangeCount, uint64* trimmedBlocks);
95
96
97// device.c
98
99status_t periph_register_device(periph_device_cookie periph_device,
100	scsi_periph_callbacks *callbacks, scsi_device scsi_device,
101	scsi_device_interface *scsi, device_node *node, bool removable,
102	int preferredCcbSize, scsi_periph_device *driver);
103status_t periph_unregister_device(scsi_periph_device_info *driver);
104char *periph_compose_device_name(device_node *device_node, const char *prefix);
105
106
107// io.c
108
109status_t periph_read_write(scsi_periph_device_info *device, scsi_ccb *request,
110	uint64 offset, size_t numBlocks, physical_entry* vecs, size_t vecCount,
111	bool isWrite, size_t* _bytesTransferred);
112status_t periph_io(scsi_periph_device_info* device, io_operation* operation,
113	size_t *_bytesTransferred);
114status_t periph_ioctl(scsi_periph_handle_info *handle, int op,
115	void *buf, size_t len);
116void periph_sync_queue_daemon(void *arg, int iteration);
117status_t vpd_page_get(scsi_periph_device_info *device, scsi_ccb* request,
118	uint8 page, void* data, uint16 length);
119
120
121// scsi_periph.c
122
123status_t periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request);
124status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb,
125	uchar cdb_len, void *data, size_t data_len, int ccb_flags);
126
127
128// sync.c
129
130err_res periph_synchronize_cache(scsi_periph_device_info *device,
131	scsi_ccb *request);
132
133#endif	/* __SCSI_PERIPH_INT_H__ */
134