Annotation of /trunk/hal/patches/hal-0.5.10-when-initial-disc-type-detection-fails-fall-back-to.patch
Parent Directory | Revision Log
Revision 597 -
(hide annotations)
(download)
Mon May 19 19:05:19 2008 UTC (16 years, 4 months ago) by niro
File size: 6149 byte(s)
Mon May 19 19:05:19 2008 UTC (16 years, 4 months ago) by niro
File size: 6149 byte(s)
-gentoo patches
1 | niro | 597 | From cccf577b31c9b875d875122224dd2d854eba43f3 Mon Sep 17 00:00:00 2001 |
2 | From: Sjoerd Simons <sjoerd@luon.net> | ||
3 | Date: Fri, 7 Dec 2007 22:50:54 +0100 | ||
4 | Subject: [PATCH] when initial disc type detection fails fall back to a alternate detection method | ||
5 | |||
6 | This patch from David Castelow provides a fallback if the | ||
7 | GET CONFIGURATION scsi command fails. This allows disc type detection | ||
8 | on older drivers. | ||
9 | --- | ||
10 | hald/linux/probing/linux_dvd_rw_utils.c | 160 ++++++++++++++++++++++++++++++- | ||
11 | 1 files changed, 158 insertions(+), 2 deletions(-) | ||
12 | |||
13 | diff --git a/hald/linux/probing/linux_dvd_rw_utils.c b/hald/linux/probing/linux_dvd_rw_utils.c | ||
14 | index 3760a99..46c3ad4 100644 | ||
15 | --- a/hald/linux/probing/linux_dvd_rw_utils.c | ||
16 | +++ b/hald/linux/probing/linux_dvd_rw_utils.c | ||
17 | @@ -784,6 +784,160 @@ get_disc_capacity_for_type (int fd, | ||
18 | return retval; | ||
19 | } | ||
20 | |||
21 | + | ||
22 | +static int | ||
23 | +get_mmc_profile (int fd, int * isblank) | ||
24 | +{ | ||
25 | + ScsiCommand * cmd; | ||
26 | + int retval = -1; | ||
27 | + unsigned char formats[260],disc_info[32]; | ||
28 | + unsigned char page[20]; | ||
29 | + unsigned char buf[8],inq[128]; | ||
30 | + int profile=0,once=1,blank=0,err,erasable=0; | ||
31 | + unsigned int len; | ||
32 | + | ||
33 | + cmd = scsi_command_new_from_fd (fd); | ||
34 | + | ||
35 | + /* For valgrind */ | ||
36 | + memset (&page, 0, sizeof (page)); | ||
37 | + memset (&buf, 0, sizeof (buf)); | ||
38 | + memset (&inq, 0, sizeof (inq)); | ||
39 | + memset (&disc_info, 0, sizeof (disc_info)); | ||
40 | + memset (&formats, 0, sizeof (formats)); | ||
41 | + | ||
42 | + /* | ||
43 | + INQUIRY is considered to be "non-intrusive" in a sense that it | ||
44 | + won't interfere with any other operation nor clear sense data, | ||
45 | + which might be important to retain for security reasons. | ||
46 | + */ | ||
47 | + | ||
48 | + scsi_command_init(cmd,0,0x12); /* INQUIRY */ | ||
49 | + scsi_command_init(cmd,4,36); | ||
50 | + scsi_command_init(cmd,5,0); | ||
51 | + if ((err=scsi_command_transport(cmd,READ,inq,36))) { | ||
52 | + /*sperror ("INQUIRY",err);*/ | ||
53 | + goto bail; | ||
54 | + } | ||
55 | + | ||
56 | + /* make sure we're talking to MMC unit, for security reasons... */ | ||
57 | + if ((inq[0]&0x1F) != 5) { | ||
58 | + fprintf (stderr, "Could not determine drive profile: not an MMC unit!\n"); | ||
59 | + goto bail; | ||
60 | + } | ||
61 | + | ||
62 | + do { | ||
63 | + scsi_command_init(cmd,0,0x46); | ||
64 | + scsi_command_init(cmd,8,sizeof(buf)); | ||
65 | + scsi_command_init(cmd,9,0); | ||
66 | + if ((err=scsi_command_transport(cmd,READ,buf,sizeof(buf)))) { | ||
67 | + /*sperror ("GET CONFIGURATION",err);*/ | ||
68 | + /* this is not a fatal error -- some older drives support MMC-1 | ||
69 | + * but don't support the GET CONFIGURATION command (which is part | ||
70 | + * of the MMC-2 spec). */ | ||
71 | + } else { | ||
72 | + if ((profile = buf[6]<<8|buf[7]) || !once) break; | ||
73 | + } | ||
74 | + | ||
75 | + // no media? | ||
76 | + scsi_command_init(cmd,0,0); // TEST UNIT READY | ||
77 | + scsi_command_init(cmd,5,0); | ||
78 | + if ((scsi_command_transport(cmd,READ,buf,sizeof(buf))&0xFFF00) != 0x23A00) break; | ||
79 | + | ||
80 | + // try to load tray... | ||
81 | + scsi_command_init(cmd,0,0x1B); // START/STOP UNIT | ||
82 | + scsi_command_init(cmd,4,0x3); // "Load" | ||
83 | + scsi_command_init(cmd,5,0); | ||
84 | + if ((err=scsi_command_transport(cmd,READ,buf,sizeof(buf)))) { | ||
85 | + /*sperror ("LOAD TRAY",err);*/ | ||
86 | + fprintf (stderr, "Could not determine drive profile: Error loading drive tray\n"); | ||
87 | + goto bail; | ||
88 | + } | ||
89 | + | ||
90 | + /* wait_for_unit (cmd);*/ | ||
91 | + } while (once--); | ||
92 | + | ||
93 | + scsi_command_init(cmd,0,0x51); // READ DISC INFORMATION | ||
94 | + scsi_command_init(cmd,8,sizeof(disc_info)); | ||
95 | + scsi_command_init(cmd,9,0); | ||
96 | + if ((err=scsi_command_transport(cmd,READ,disc_info,sizeof(disc_info)))) { | ||
97 | + /*sperror ("READ DISC INFORMATION",err);*/ | ||
98 | + fprintf (stderr, "Could not fully determine drive profile %x: Error reading disc information\n", profile); | ||
99 | + goto bail; | ||
100 | + } | ||
101 | + | ||
102 | + // see if it's blank media | ||
103 | + if ((disc_info[2]&3) == 0) blank=1; | ||
104 | + | ||
105 | + if (!profile ) { | ||
106 | + /* if the profile has not yet been set, we're dealing with an older | ||
107 | + * CD-R or CD-RW burner (which doesn't know the GET CONFIGURATION | ||
108 | + * command. Do some digging into the disc type to figure out what's | ||
109 | + * in the drive */ | ||
110 | + erasable = ((disc_info[2] & 16)); | ||
111 | + if (blank && !erasable) { | ||
112 | + profile = 0x09; /* CD-R */ | ||
113 | + } else if (erasable) { | ||
114 | + profile = 0x0a; /* CD-RW */ | ||
115 | + } else if (disc_info[8] == 0x00) { | ||
116 | + profile = 0x08; /* Commercial CDs and Audio CD */ | ||
117 | + } else { | ||
118 | + fprintf (stderr, "Could not determine profile or type of media\n"); | ||
119 | + goto bail; | ||
120 | + } | ||
121 | + } | ||
122 | + | ||
123 | + if ((profile != 0x1A && profile != 0x13 && profile != 0x12)) { | ||
124 | + retval = profile; | ||
125 | + } | ||
126 | + else { | ||
127 | + scsi_command_init(cmd,0,0x23); // READ FORMAT CAPACITIES | ||
128 | + scsi_command_init(cmd,8,12); | ||
129 | + scsi_command_init(cmd,9,0); | ||
130 | + if ((err=scsi_command_transport(cmd,READ,formats,12))) { | ||
131 | + /*sperror ("READ FORMAT CAPACITIES",err);*/ | ||
132 | + fprintf (stderr, "Could not determine drive profile: " | ||
133 | + "Error reading format capacities\n"); | ||
134 | + goto bail; | ||
135 | + } | ||
136 | + | ||
137 | + len = formats[3]; | ||
138 | + if (len&7 || len<16) { | ||
139 | + fprintf (stderr, "Could not determine drive profile: " | ||
140 | + "Format allocation length isn't sane\n"); | ||
141 | + goto bail; | ||
142 | + } | ||
143 | + | ||
144 | + scsi_command_init(cmd,0,0x23); // READ FORMAT CAPACITIES | ||
145 | + scsi_command_init(cmd,7,(4+len)>>8); | ||
146 | + scsi_command_init(cmd,8,(4+len)&0xFF); | ||
147 | + scsi_command_init(cmd,9,0); | ||
148 | + if ((err=scsi_command_transport(cmd,READ,formats,4+len))) { | ||
149 | + /*sperror ("READ FORMAT CAPACITIES",err);*/ | ||
150 | + fprintf (stderr, "Could not determine drive profile: " | ||
151 | + "Error reading format capacities (2)\n"); | ||
152 | + goto bail; | ||
153 | + } | ||
154 | + | ||
155 | + if (len != formats[3]) { | ||
156 | + fprintf (stderr, "Could not determine drive profile: " | ||
157 | + "parameter length inconsistency\n"); | ||
158 | + goto bail; | ||
159 | + } | ||
160 | + | ||
161 | + // see if it's not formatted | ||
162 | + if ((formats[8]&3) != 2) blank = 1; | ||
163 | + | ||
164 | + retval = profile; | ||
165 | + } | ||
166 | + | ||
167 | + /* Only touch isblank if we have read the profile correctly. */ | ||
168 | + if ( retval != -1 ) { | ||
169 | + *isblank = blank; | ||
170 | + } | ||
171 | +bail: | ||
172 | + return retval; | ||
173 | +} | ||
174 | + | ||
175 | int | ||
176 | get_disc_type (int fd) | ||
177 | { | ||
178 | @@ -798,14 +952,16 @@ get_disc_type (int fd) | ||
179 | scsi_command_init (cmd, 8, 8); | ||
180 | scsi_command_init (cmd, 9, 0); | ||
181 | if (scsi_command_transport (cmd, READ, header, 8)) { | ||
182 | + int isblank; | ||
183 | /* GET CONFIGURATION failed */ | ||
184 | scsi_command_free (cmd); | ||
185 | - return -1; | ||
186 | + /* Try alternative method */ | ||
187 | + retval = get_mmc_profile(fd,&isblank); | ||
188 | + return retval; /* get_mmc_profile returns -1 on error too. */ | ||
189 | } | ||
190 | |||
191 | retval = (header[6]<<8)|(header[7]); | ||
192 | |||
193 | - | ||
194 | scsi_command_free (cmd); | ||
195 | return retval; | ||
196 | } | ||
197 | -- | ||
198 | 1.5.3.7 | ||
199 |