Magellan Linux

Contents of /trunk/hal/patches/hal-0.5.10-when-initial-disc-type-detection-fails-fall-back-to.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 597 - (show annotations) (download)
Mon May 19 19:05:19 2008 UTC (15 years, 11 months ago) by niro
File size: 6149 byte(s)
-gentoo patches

1 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