Magellan Linux

Annotation 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 - (hide annotations) (download)
Mon May 19 19:05:19 2008 UTC (16 years 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