1/*
2 * Copyright 2004-2008, 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
19typedef struct scsi_periph_device_info {
20	struct scsi_periph_handle_info *handles;
21
22	::scsi_device scsi_device;
23	scsi_device_interface *scsi;
24	periph_device_cookie periph_device;
25	device_node *node;
26
27	bool removal_requested;
28
29	bool removable;			// true, if device is removable
30
31	uint32 block_size;
32	int32 preferred_ccb_size;
33	int32 rw10_enabled;		// 10 byte r/w commands supported; access must be atomic
34	int32 next_tag_action;	// queuing flag for next r/w command; access must be atomic
35
36	struct mutex mutex;
37	int std_timeout;
38
39	scsi_periph_callbacks *callbacks;
40} scsi_periph_device_info;
41
42typedef struct scsi_periph_handle_info {
43	scsi_periph_device_info *device;
44	struct scsi_periph_handle_info *next, *prev;
45
46	int pending_error;		// error to be reported on all accesses
47							// (used to block access after medium change until
48							//  B_GET_MEDIA_STATUS is called)
49	periph_handle_cookie periph_handle;
50} scsi_periph_handle_info;
51
52extern device_manager_info *gDeviceManager;
53
54
55// removable.c
56
57void periph_media_changed(scsi_periph_device_info *device, scsi_ccb *ccb);
58void periph_media_changed_public(scsi_periph_device_info *device);
59status_t periph_get_media_status(scsi_periph_handle_info *handle);
60err_res periph_send_start_stop(scsi_periph_device_info *device, scsi_ccb *request,
61	bool start, bool with_LoEj);
62
63
64// error_handling.c
65
66err_res periph_check_error(scsi_periph_device_info *device, scsi_ccb *request);
67
68
69// handle.c
70
71status_t periph_handle_open(scsi_periph_device_info *device, periph_handle_cookie periph_handle,
72	scsi_periph_handle_info **res_handle);
73status_t periph_handle_close(scsi_periph_handle_info *handle);
74status_t periph_handle_free(scsi_periph_handle_info *handle);
75
76
77// block.c
78
79status_t periph_check_capacity(scsi_periph_device_info *device, scsi_ccb *ccb);
80
81
82// device.c
83
84status_t periph_register_device(periph_device_cookie periph_device,
85	scsi_periph_callbacks *callbacks, scsi_device scsi_device,
86	scsi_device_interface *scsi, device_node *node, bool removable,
87	int preferredCcbSize, scsi_periph_device *driver);
88status_t periph_unregister_device(scsi_periph_device_info *driver);
89char *periph_compose_device_name(device_node *device_node, const char *prefix);
90
91
92// io.c
93
94status_t periph_read_write(scsi_periph_device_info *device, scsi_ccb *request,
95	uint64 offset, size_t numBlocks, physical_entry* vecs, size_t vecCount,
96	bool isWrite, size_t* _bytesTransferred);
97status_t periph_io(scsi_periph_device_info* device, io_operation* operation,
98	size_t *_bytesTransferred);
99status_t periph_ioctl(scsi_periph_handle_info *handle, int op,
100	void *buf, size_t len);
101void periph_sync_queue_daemon(void *arg, int iteration);
102
103
104// scsi_periph.c
105
106status_t periph_safe_exec(scsi_periph_device_info *device, scsi_ccb *request);
107status_t periph_simple_exec(scsi_periph_device_info *device, void *cdb,
108	uchar cdb_len, void *data, size_t data_len, int ccb_flags);
109
110
111// sync.c
112
113err_res periph_synchronize_cache(scsi_periph_device_info *device,
114	scsi_ccb *request);
115
116#endif	/* __SCSI_PERIPH_INT_H__ */
117