/[qemu]/qemu/hw/esp.c
ViewVC logotype

Diff of /qemu/hw/esp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by bellard, Fri Nov 11 00:24:57 2005 UTC revision 1.5 by bellard, Mon Dec 5 20:30:36 2005 UTC
# Line 75  typedef struct ESPState { Line 75  typedef struct ESPState {
75  #define SEQ_0 0x0  #define SEQ_0 0x0
76  #define SEQ_CD 0x4  #define SEQ_CD 0x4
77    
78    /* XXX: stolen from ide.c, move to common ATAPI/SCSI library */
79    static void lba_to_msf(uint8_t *buf, int lba)
80    {
81        lba += 150;
82        buf[0] = (lba / 75) / 60;
83        buf[1] = (lba / 75) % 60;
84        buf[2] = lba % 75;
85    }
86    
87    static inline void cpu_to_ube16(uint8_t *buf, int val)
88    {
89        buf[0] = val >> 8;
90        buf[1] = val;
91    }
92    
93    static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
94    {
95        buf[0] = val >> 24;
96        buf[1] = val >> 16;
97        buf[2] = val >> 8;
98        buf[3] = val;
99    }
100    
101    /* same toc as bochs. Return -1 if error or the toc length */
102    /* XXX: check this */
103    static int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
104    {
105        uint8_t *q;
106        int len;
107        
108        if (start_track > 1 && start_track != 0xaa)
109            return -1;
110        q = buf + 2;
111        *q++ = 1; /* first session */
112        *q++ = 1; /* last session */
113        if (start_track <= 1) {
114            *q++ = 0; /* reserved */
115            *q++ = 0x14; /* ADR, control */
116            *q++ = 1;    /* track number */
117            *q++ = 0; /* reserved */
118            if (msf) {
119                *q++ = 0; /* reserved */
120                lba_to_msf(q, 0);
121                q += 3;
122            } else {
123                /* sector 0 */
124                cpu_to_ube32(q, 0);
125                q += 4;
126            }
127        }
128        /* lead out track */
129        *q++ = 0; /* reserved */
130        *q++ = 0x16; /* ADR, control */
131        *q++ = 0xaa; /* track number */
132        *q++ = 0; /* reserved */
133        if (msf) {
134            *q++ = 0; /* reserved */
135            lba_to_msf(q, nb_sectors);
136            q += 3;
137        } else {
138            cpu_to_ube32(q, nb_sectors);
139            q += 4;
140        }
141        len = q - buf;
142        cpu_to_ube16(buf, len - 2);
143        return len;
144    }
145    
146    /* mostly same info as PearPc */
147    static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf,
148                                  int session_num)
149    {
150        uint8_t *q;
151        int len;
152        
153        q = buf + 2;
154        *q++ = 1; /* first session */
155        *q++ = 1; /* last session */
156    
157        *q++ = 1; /* session number */
158        *q++ = 0x14; /* data track */
159        *q++ = 0; /* track number */
160        *q++ = 0xa0; /* lead-in */
161        *q++ = 0; /* min */
162        *q++ = 0; /* sec */
163        *q++ = 0; /* frame */
164        *q++ = 0;
165        *q++ = 1; /* first track */
166        *q++ = 0x00; /* disk type */
167        *q++ = 0x00;
168        
169        *q++ = 1; /* session number */
170        *q++ = 0x14; /* data track */
171        *q++ = 0; /* track number */
172        *q++ = 0xa1;
173        *q++ = 0; /* min */
174        *q++ = 0; /* sec */
175        *q++ = 0; /* frame */
176        *q++ = 0;
177        *q++ = 1; /* last track */
178        *q++ = 0x00;
179        *q++ = 0x00;
180        
181        *q++ = 1; /* session number */
182        *q++ = 0x14; /* data track */
183        *q++ = 0; /* track number */
184        *q++ = 0xa2; /* lead-out */
185        *q++ = 0; /* min */
186        *q++ = 0; /* sec */
187        *q++ = 0; /* frame */
188        if (msf) {
189            *q++ = 0; /* reserved */
190            lba_to_msf(q, nb_sectors);
191            q += 3;
192        } else {
193            cpu_to_ube32(q, nb_sectors);
194            q += 4;
195        }
196    
197        *q++ = 1; /* session number */
198        *q++ = 0x14; /* ADR, control */
199        *q++ = 0;    /* track number */
200        *q++ = 1;    /* point */
201        *q++ = 0; /* min */
202        *q++ = 0; /* sec */
203        *q++ = 0; /* frame */
204        if (msf) {
205            *q++ = 0;
206            lba_to_msf(q, 0);
207            q += 3;
208        } else {
209            *q++ = 0;
210            *q++ = 0;
211            *q++ = 0;
212            *q++ = 0;
213        }
214    
215        len = q - buf;
216        cpu_to_ube16(buf, len - 2);
217        return len;
218    }
219    
220  static void handle_satn(ESPState *s)  static void handle_satn(ESPState *s)
221  {  {
222      uint8_t buf[32];      uint8_t buf[32];
# Line 128  static void handle_satn(ESPState *s) Line 270  static void handle_satn(ESPState *s)
270          memcpy(&s->ti_buf[8], "QEMU   ", 8);          memcpy(&s->ti_buf[8], "QEMU   ", 8);
271          s->ti_buf[2] = 1;          s->ti_buf[2] = 1;
272          s->ti_buf[3] = 2;          s->ti_buf[3] = 2;
273            s->ti_buf[4] = 32;
274          s->ti_dir = 1;          s->ti_dir = 1;
275          s->ti_size = 36;          s->ti_size = 36;
276          break;          break;
# Line 190  static void handle_satn(ESPState *s) Line 333  static void handle_satn(ESPState *s)
333              s->ti_dir = 0;              s->ti_dir = 0;
334              break;              break;
335          }          }
336        case 0x43:
337            {
338                int start_track, format, msf, len;
339    
340                msf = buf[2] & 2;
341                format = buf[3] & 0xf;
342                start_track = buf[7];
343                bdrv_get_geometry(s->bd[target], &nb_sectors);
344                DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
345                switch(format) {
346                case 0:
347                    len = cdrom_read_toc(nb_sectors, buf, msf, start_track);
348                    if (len < 0)
349                        goto error_cmd;
350                    s->ti_size = len;
351                    break;
352                case 1:
353                    /* multi session : only a single session defined */
354                    memset(buf, 0, 12);
355                    buf[1] = 0x0a;
356                    buf[2] = 0x01;
357                    buf[3] = 0x01;
358                    s->ti_size = 12;
359                    break;
360                case 2:
361                    len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track);
362                    if (len < 0)
363                        goto error_cmd;
364                    s->ti_size = len;
365                    break;
366                default:
367                error_cmd:
368                    DPRINTF("Read TOC error\n");
369                    // XXX error handling
370                    break;
371                }
372                s->ti_dir = 1;
373                break;
374            }
375      default:      default:
376          DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);          DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);
377          break;          break;

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26