xref: /haiku/src/add-ons/kernel/bus_managers/scsi/sim_interface.cpp (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
1 /*
2  * Copyright 2004-2008, Haiku, Inc. All RightsReserved.
3  * Copyright 2002/03, Thomas Kurschel. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 
8 /*
9 	Controllers use this interface to interact with bus manager.
10 */
11 
12 
13 #include "scsi_internal.h"
14 #include "queuing.h"
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 
21 /**	new scsi controller added
22  *	in return, we register a new scsi bus node and let its fixed
23  *	consumer (the SCSI device layer) automatically scan it for devices
24  */
25 
26 static status_t
27 scsi_controller_added(device_node *parent)
28 {
29 	const char *controller_name;
30 	int32 pathID;
31 
32 	SHOW_FLOW0(4, "");
33 
34 	if (pnp->get_attr_string(parent, SCSI_DESCRIPTION_CONTROLLER_NAME,
35 			&controller_name, false) != B_OK) {
36 		dprintf("scsi: ignored controller - controller name missing\n");
37 		return B_ERROR;
38 	}
39 
40 	pathID = pnp->create_id(SCSI_PATHID_GENERATOR);
41 	if (pathID < 0) {
42 		dprintf("scsi: Cannot register SCSI controller %s - out of path IDs\n",
43 			controller_name);
44 		return B_ERROR;
45 	}
46 
47 	{
48 		device_attr attrs[] = {
49 			{ B_DEVICE_PRETTY_NAME, B_STRING_TYPE,
50 				{ .string = "SCSI Controller" }},
51 
52 			// remember who we are
53 			// (could use the controller name, but probably some software would choke)
54 			// TODO create_id() generates a 32 bit ranged integer but we need only 8 bits
55 			{ SCSI_BUS_PATH_ID_ITEM, B_UINT8_TYPE, { .ui8 = (uint8)pathID }},
56 
57 			// tell PnP manager to clean up ID
58 //			{ PNP_MANAGER_ID_GENERATOR, B_STRING_TYPE, { .string = SCSI_PATHID_GENERATOR }},
59 //			{ PNP_MANAGER_AUTO_ID, B_UINT32_TYPE, { .ui32 = path_id }},
60 			{}
61 		};
62 
63 		return pnp->register_node(parent, SCSI_BUS_MODULE_NAME, attrs, NULL,
64 			NULL);
65 	}
66 }
67 
68 
69 static status_t
70 scsi_controller_init(device_node *node, void **_cookie)
71 {
72 	*_cookie = node;
73 	return B_OK;
74 }
75 
76 
77 static status_t
78 scsi_controller_register_raw_device(void *_cookie)
79 {
80 	device_node *node = (device_node *)_cookie;
81 	uint32 channel;
82 	uint8 pathID;
83 	char *name;
84 
85 #if 1
86 // TODO: this seems to cause a crash in some configurations, and needs to be investigated!
87 //		see bug #389 and #393.
88 // TODO: check if the above is still true
89 	if (pnp->get_attr_uint32(node, "ide/channel_id", &channel, true) == B_OK) {
90 		// this is actually an IDE device, we don't need to publish
91 		// a bus device for those
92 		return B_OK;
93 	}
94 #endif
95 	pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &pathID, false);
96 
97 	// put that on heap to not overflow the limited kernel stack
98 	name = (char*)malloc(PATH_MAX + 1);
99 	if (name == NULL)
100 		return B_NO_MEMORY;
101 
102 	snprintf(name, PATH_MAX + 1, "bus/scsi/%d/bus_raw", pathID);
103 
104 	return pnp->publish_device(node, name, SCSI_BUS_RAW_MODULE_NAME);
105 }
106 
107 
108 static status_t
109 std_ops(int32 op, ...)
110 {
111 	switch (op) {
112 		case B_MODULE_INIT:
113 		case B_MODULE_UNINIT:
114 			return B_OK;
115 
116 		default:
117 			return B_ERROR;
118 	}
119 }
120 
121 
122 scsi_for_sim_interface scsi_for_sim_module =
123 {
124 	{
125 		{
126 			SCSI_FOR_SIM_MODULE_NAME,
127 			0,
128 			std_ops
129 		},
130 
131 		NULL,	// supported devices
132 		scsi_controller_added,
133 		scsi_controller_init,
134 		NULL,	// uninit
135 		scsi_controller_register_raw_device,
136 		NULL,	// rescan
137 		NULL,	// removed
138 	},
139 
140 	scsi_requeue_request,
141 	scsi_resubmit_request,
142 	scsi_request_finished,
143 
144 	scsi_alloc_dpc,
145 	scsi_free_dpc,
146 	scsi_schedule_dpc,
147 
148 	scsi_block_bus,
149 	scsi_unblock_bus,
150 	scsi_block_device,
151 	scsi_unblock_device,
152 
153 	scsi_cont_send_bus,
154 	scsi_cont_send_device
155 };
156