Hi there. I seem to have some problems with my cd read program. I've attached a small prototype program that for some reason hangs in atprq, even though I use a timeout of 5 seconds. The program reads a cd in raw format using the MMC READ_CD command. It works fine :) except that it never manages to finish because of the hang. The hang doesn't seem to be linked to any specific place on the cd, but it might be linked to my ignorance ;)
Though the program is hanging forever, the dvd-drive(SD-616F) is still usable, eg. I can mount the cd in the drive or even start a second copy of my program. A trace of the hanging process from DDB reveals the following: ------------ db> tr 199 mi_switch(c1f8c480,c1de6d2c,0,d791bd2c,0) at mi_switch+0x174 tsleep(c1f8c480,10,c0266201,0,c4546101) at tsleep+0x19d atapi_queue_cmd(c1de6d2c,c1fef80c,c2098000,5be0,11) at atapi_queue_cmd+0x13f ataioctl(c02cefb0,c4546101,c1fef800,1,d478f1e0) at ataioctl+0x558 spec_ioctl(d791bde4,d791bdcc,c01efac9,d791bde4,d791be74) at spec_ioctl+0x26 spec_vnoperate(d791bde4,d791be74,c018265f,d791bde4,c200b000) at spec_vnoperate+0 x15 ufs_vnoperatespec(d791bde4,c200b000,0,454,c0294f60) at ufs_vnoperatespec+0x15 vn_ioctl(c200b000,c4546101,c1fef800,d478f1e0,d478f1e0) at vn_ioctl+0x10f ioctl(d478f1e0,d791bf80,1,bfbffc3c,bfbffc44) at ioctl+0x20a syscall2(2f,2f,2f,bfbffc44,bfbffc3c) at syscall2+0x1f5 Xint0x80_syscall() at Xint0x80_syscall+0x25 ------------- My program sends the CCB with the MMC to the device using the IOCATA ioctl on /dev/ata. Is this the right API to use to do this or are there some better way of doing it? I've attached the source and dmesg. I'm thankful for any help, -Richard
#include <sys/types.h> #include <sys/ata.h> #include <sys/ioctl.h> #include <fcntl.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define DATASIZE 2352 #define SUBSIZE 96 #ifdef READSUB #define BLKSIZE (DATASIZE + SUBSIZE) #else #define BLKSIZE DATASIZE #endif #define NBLOCKS 10 int main(void) { int dev, bin, sub; int32_t lba, last_lba, sizes[2]; char data[BLKSIZE * NBLOCKS]; struct ata_cmd iocmd; dev = open("/dev/ata", O_RDONLY); if (dev == -1) { perror("open"); return 1; } bin = open("out.bin", O_WRONLY | O_CREAT | O_TRUNC, 00644); if (bin == -1) { perror("open"); return 1; } #ifdef READSUB sub = open("out.sub", O_WRONLY | O_CREAT | O_TRUNC, 00644); if (sub == -1) { perror("open"); return 1; } #endif bzero(&iocmd, sizeof(struct ata_cmd)); iocmd.channel = 1; iocmd.device = 0; iocmd.cmd = ATAPICMD; iocmd.u.atapi.flags = ATAPI_CMD_READ; iocmd.u.atapi.data = (caddr_t *)sizes; iocmd.u.atapi.count = 8; iocmd.u.atapi.timeout = 5; iocmd.u.atapi.ccb[0] = 0x25; /* READ_CAPACITY */ if (ioctl(dev, IOCATA, &iocmd) == -1) { perror("capacity"); return 1; } if (iocmd.u.atapi.error) { printf("ATAPI error: %d\n", iocmd.u.atapi.error); return 1; } last_lba = ntohl(sizes[0]); printf("capacity: %d\n", last_lba + 1); for (lba = 0; lba <= last_lba; lba += NBLOCKS) { int i; int32_t blocks; blocks = 1 + last_lba - lba; if (blocks > NBLOCKS) blocks = NBLOCKS; bzero(data, BLKSIZE * NBLOCKS); bzero(&iocmd, sizeof(struct ata_cmd)); iocmd.channel = 1; iocmd.device = 0; iocmd.cmd = ATAPICMD; iocmd.u.atapi.flags = ATAPI_CMD_READ; iocmd.u.atapi.data = (caddr_t *)data; iocmd.u.atapi.count = BLKSIZE * NBLOCKS; iocmd.u.atapi.timeout = 5; iocmd.u.atapi.ccb[0] = 0xbe; /* ATAPI_READ_CD */ iocmd.u.atapi.ccb[1] = 0; iocmd.u.atapi.ccb[2] = lba >> 24; iocmd.u.atapi.ccb[3] = lba >> 16; iocmd.u.atapi.ccb[4] = lba >> 8; iocmd.u.atapi.ccb[5] = lba; iocmd.u.atapi.ccb[8] = NBLOCKS; iocmd.u.atapi.ccb[9] = 0xf8; /* SYNC & HEADERS & DATA & EDC */ #ifdef READSUB iocmd.u.atapi.ccb[10] = 1; #else iocmd.u.atapi.ccb[10] = 0; #endif /* THE HANG OCCURS ON THE NEXT LINE */ if (ioctl(dev, IOCATA, &iocmd) == -1) { perror("ioctl"); return 1; } if (iocmd.u.atapi.error) { printf("ATAPI error: %d\n", iocmd.u.atapi.error); return 1; } printf("read sector %d\r", lba); fflush(stdout); for (i = 0; i < blocks; i++) { write(bin, data + i * BLKSIZE, DATASIZE); #ifdef READSUB write(sub, data + i * BLKSIZE + DATASIZE, SUBSIZE); #endif } } printf("\n"); return 0; }
Copyright (c) 1992-2002 The FreeBSD Project. Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994 The Regents of the University of California. All rights reserved. FreeBSD 4.6-RC #0: Sat May 25 14:33:36 CEST 2002 [EMAIL PROTECTED]:/usr/obj/usr/src/sys/BLACKBOX Timecounter "i8254" frequency 1193182 Hz Timecounter "TSC" frequency 1470007480 Hz CPU: AMD Athlon(tm) XP 1700+ (1470.01-MHz 686-class CPU) Origin = "AuthenticAMD" Id = 0x662 Stepping = 2 Features=0x383f9ff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE> AMD Features=0xc0480000<<b19>,AMIE,DSP,3DNow!> real memory = 536805376 (524224K bytes) avail memory = 518995968 (506832K bytes) Preloaded elf kernel "kernel" at 0xc0345000. Pentium Pro MTRR support enabled Using $PIR table, 7 entries at 0xc00fdef0 npx0: <math processor> on motherboard npx0: INT 16 interface pcib0: <Host to PCI bridge> on motherboard pci0: <PCI bus> on pcib0 pcib1: <PCI to PCI bridge (vendor=1106 device=b099)> at device 1.0 on pci0 pci1: <PCI bus> on pcib1 pci1: <NVidia model 0201 graphics accelerator> at 0.0 irq 11 pcm0: <Creative EMU10K1> port 0xd000-0xd01f irq 11 at device 9.0 on pci0 vr0: <VIA VT6102 Rhine II 10/100BaseTX> port 0xd800-0xd8ff mem 0xe3000000-0xe30000ff irq 10 at device 12.0 on pci0 vr0: Ethernet address: 00:50:ba:1c:81:29 miibus0: <MII bus> on vr0 ukphy0: <Generic IEEE 802.3u media interface> on miibus0 ukphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto isab0: <PCI to ISA bridge (vendor=1106 device=3074)> at device 17.0 on pci0 isa0: <ISA bus> on isab0 atapci0: <VIA 8233 ATA100 controller> port 0xdc00-0xdc0f at device 17.1 on pci0 ata0: at 0x1f0 irq 14 on atapci0 ata1: at 0x170 irq 15 on atapci0 uhci0: <VIA 83C572 USB controller> port 0xe000-0xe01f irq 10 at device 17.2 on pci0 usb0: <VIA 83C572 USB controller> on uhci0 usb0: USB revision 1.0 uhub0: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub0: 2 ports with 2 removable, self powered ums0: Logitech USB Mouse, rev 1.10/6.10, addr 2, iclass 3/1 ums0: 4 buttons and Z dir. uhci1: <VIA 83C572 USB controller> port 0xe400-0xe41f irq 10 at device 17.3 on pci0 usb1: <VIA 83C572 USB controller> on uhci1 usb1: USB revision 1.0 uhub1: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub1: 2 ports with 2 removable, self powered uhci2: <VIA 83C572 USB controller> port 0xe800-0xe81f irq 10 at device 17.4 on pci0 usb2: <VIA 83C572 USB controller> on uhci2 usb2: USB revision 1.0 uhub2: VIA UHCI root hub, class 9/0, rev 1.00/1.00, addr 1 uhub2: 2 ports with 2 removable, self powered orm0: <Option ROM> at iomem 0xcc000-0xd3fff on isa0 fdc0: <NEC 72065B or clone> at port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on isa0 fdc0: FIFO enabled, 8 bytes threshold fd0: <1440-KB 3.5" drive> on fdc0 drive 0 atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 on isa0 atkbd0: <AT Keyboard> flags 0x1 irq 1 on atkbdc0 kbd0 at atkbd0 vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0 sc0: <System console> at flags 0x100 on isa0 sc0: VGA <16 virtual consoles, flags=0x300> sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0 sio0: type 16550A sio1 at port 0x2f8-0x2ff irq 3 on isa0 sio1: type 16550A ad0: 57241MB <ST360021A> [116301/16/63] at ata0-master UDMA100 acd0: DVD-ROM <SAMSUNG DVD-ROM SD-616F> at ata1-master UDMA33 acd1: CD-RW <12X8X32> at ata1-slave WDMA2 Mounting root from ufs:/dev/ad0s2a