xref: /haiku/src/add-ons/kernel/partitioning_systems/session/session.cpp (revision b671e9bbdbd10268a042b4f4cc4317ccd03d105e)
1 /*
2  * Copyright 2003 Tyler Akidau, haiku@akidau.net
3  * Distributed under the terms of the MIT License.
4  */
5 
6 /*!
7 	\file session.cpp
8 	\brief Disk device manager partition module for CD/DVD sessions.
9 */
10 
11 #include <unistd.h>
12 
13 #include <ddm_modules.h>
14 #include <DiskDeviceTypes.h>
15 #include <KernelExport.h>
16 
17 #include "Debug.h"
18 #include "Disc.h"
19 
20 
21 #define SESSION_PARTITION_MODULE_NAME "partitioning_systems/session/v1"
22 #define SESSION_PARTITION_NAME "Multisession Storage Device"
23 
24 
25 static status_t
26 standard_operations(int32 op, ...)
27 {
28 	switch (op) {
29 		case B_MODULE_INIT:
30 		case B_MODULE_UNINIT:
31 			return B_OK;
32 	}
33 
34 	return B_ERROR;
35 }
36 
37 
38 static float
39 identify_partition(int fd, partition_data *partition, void **cookie)
40 {
41 	DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, "
42 		"size: %Ld, block_size: %ld, flags: 0x%lx", fd,
43 		partition->id, partition->offset, partition->size,
44 		partition->block_size, partition->flags));
45 
46 	device_geometry geometry;
47 	float result = -1;
48 	if (partition->flags & B_PARTITION_IS_DEVICE
49 		&& partition->block_size == 2048
50 		&& ioctl(fd, B_GET_GEOMETRY, &geometry) == 0
51 		&& geometry.device_type == B_CD) {
52 		Disc *disc = new Disc(fd);
53 		if (disc && disc->InitCheck() == B_OK) {
54 			*cookie = static_cast<void*>(disc);
55 			result = 0.7;
56 		} else
57 			delete disc;
58 	}
59 	PRINT(("returning %ld\n", int32(result * 10000)));
60 	return result;
61 }
62 
63 
64 static status_t
65 scan_partition(int fd, partition_data *partition, void *cookie)
66 {
67 	DEBUG_INIT_ETC(NULL, ("fd: %d, id: %ld, offset: %Ld, size: %Ld, "
68 		"block_size: %ld, cookie: %p", fd, partition->id, partition->offset,
69 		partition->size, partition->block_size, cookie));
70 
71 	Disc *disc = static_cast<Disc*>(cookie);
72 	partition->status = B_PARTITION_VALID;
73 	partition->flags |= B_PARTITION_PARTITIONING_SYSTEM
74 		| B_PARTITION_READ_ONLY;
75 	partition->content_size = partition->size;
76 
77 	Session *session = NULL;
78 	status_t error = B_OK;
79 	for (int i = 0; (session = disc->GetSession(i)); i++) {
80 		partition_data *child = create_child_partition(partition->id,
81 			i, partition->offset + session->Offset(), session->Size(), -1);
82 		if (!child) {
83 			PRINT(("Unable to create child at index %d.\n", i));
84 			// something went wrong
85 			error = B_ERROR;
86 			break;
87 		}
88 		child->block_size = session->BlockSize();
89 		child->flags |= session->Flags();
90 		child->type = strdup(session->Type());
91 		delete session;
92 		if (!child->type) {
93 			error = B_NO_MEMORY;
94 			break;
95 		}
96 		child->parameters = NULL;
97 	}
98 	PRINT(("error: 0x%lx, `%s'\n", error, strerror(error)));
99 	RETURN(error);
100 }
101 
102 
103 static void
104 free_identify_partition_cookie(partition_data */*partition*/, void *cookie)
105 {
106 	DEBUG_INIT_ETC(NULL, ("cookie: %p", cookie));
107 	delete static_cast<Disc*>(cookie);
108 }
109 
110 
111 static partition_module_info sSessionModule = {
112 	{
113 		SESSION_PARTITION_MODULE_NAME,
114 		0,
115 		standard_operations
116 	},
117 	"session",							// short_name
118 	SESSION_PARTITION_NAME,				// pretty_name
119 	0,									// flags
120 
121 	// scanning
122 	identify_partition,					// identify_partition
123 	scan_partition,						// scan_partition
124 	free_identify_partition_cookie,		// free_identify_partition_cookie
125 	NULL,								// free_partition_cookie
126 	NULL,								// free_partition_content_cookie
127 };
128 
129 partition_module_info *modules[] = {
130 	&sSessionModule,
131 	NULL
132 };
133