Date: Tue, 22 Dec 1998 06:18:01 -0600 From: David Deaven <deaven@execpc.com> To: Steve Willoughby <steve@alchemy.com> Cc: freebsd-questions@FreeBSD.ORG Subject: Re: problem with CD-R writing. Message-ID: <199812221214.GAA16013@pop05.execpc.com> In-Reply-To: Your message of "Sat, 19 Dec 1998 13:29:58 PST." <Pine.BSF.4.01.9812191312430.3532-100000@elemental.alchemy.com>
next in thread | previous in thread | raw e-mail | index | archive | help
This is a multipart MIME message. --==_Exmh_18900079500 Content-Type: text/plain; charset=us-ascii Have you tried using this drive as a CD-ROM (read-only)? The SCSI error you are getting is very basic -- all SCSI devices (besides CD-Rs) should support the TEST_UNIT_READY command, so it really looks like a hardware problem... I've attached a small C program that uses the FreeBSD SCSI ioctls to do a test unit ready command when run with no arguments. When I run it on my SCSI 2 CDRW drive (which works great with cdrecord) I get: # ./scsi bus0 target1 lun0 sending SCSI command 00 00 00 00 00 00 test unit ready: sense ASC=0 ASCQ=0 You might want to try it out to pursue this issue; it might be easier to debug than going through Schilling's generic scg driver code in cdrecord. You might need to change the device, which is hard-coded to be /dev/cd0c in main(). Finally, my probe looks like this, almost exactly like yours: ncr0 <ncr 53c810a fast10 scsi> rev 18 int a irq 11 on pci0:11:0 ncr0 waiting for scsi devices to settle (ncr0:1:0): "RICOH MP6201S 2.03" type 5 removable SCSI 2 cd0(ncr0:1:0): CD-ROM cd present [203237 x 2048 byte records] Good luck, hope this is of some help. Dave Deaven >I have a generic SCSI CD-R drive (the brand is Smart and Friendly, which I'd >never heard of, but I (naively?) thought that SCSI drives were SCSI drives >were SCSI drives)... > >The drive works fine under Win95, so I don't think the problem is that the >hardware's broken, but when I try to run it in my FreeBSD 2.2.7 system, >I get the following. I hope someone out there has a clue to help. >Thanks in advance. > >Okay, here are the gory details... > >The drive is recognized at boot time: > (ahc0:4:0): "SAF CD-RW226 1.12" type 5 removable SCSI 2 > cd0(ahc0:4:0): CD-ROM cd present [400000 x 2048 byte records] > >The second line is puzzling since there was no cd present, but I didn't >think much of that. > >When using cdrecord, I consistently get the following, no matter what operatio >n >I try to perform: > > # cdrecord -inq dev=4,0 > Cdrecord release 1.6 Copyright (C) 1995-1998 Jvrg Schilling > scsidev: '4,0' > scsibus: 0 target: 4 lun: 0 > cdrecord: Cannot do inquiry for CD-Recorder. > cdrecord: Undefined error: 0. test unit ready: scsi sendcmd: fatal error > CDB: 00 00 00 00 00 00 > cmd finished after 0.000s timeout 40s > >SCSI scans don't find anything: > > # cdrecord -scanbus > Cdrecord release 1.6 Copyright (C) 1995-1998 Jvrg Schilling > cdrecord: No target found. > >I also tried cd-write, but that just spews Tk errors about undefined variables >(TkPriv, etc.), and that's running it with freshly-compiled Tcl/Tk 8.0.3+ libs >and Tix 4.1.8.0, so I don't think that's the problem. But one thing that doe >s >manage to come up with cd-write is the following which I get from the >"copy cd" command: > >It IDs the drive as "SAF CD-RW226 1.12", which I believe is the SCSI ID string >(since that came up at the boot-time scan too), but I get the TEST UNIT READY >failure message: > > TEST UNIT READY command failed > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > flags=0x1 senselen_used=32 status=0x02 retsts=0x03 error=0x0 > 70 00 02 00 00 00 00 0a 00 00 00 00 3a 00 00 00 00 00 00 ff 94 3e 63 00 00 > 00 00 00 00 00 00 00 > >Do I just have a hopelessly incompatible CD-R drive, or can I do something >to the cdrecod sources, or did I miss something obvious? > >TIA, >Steve Willoughby >steve@alchemy.com > > >To Unsubscribe: send mail to majordomo@FreeBSD.org >with "unsubscribe freebsd-questions" in the body of the message > --==_Exmh_18900079500 Content-Type: text/plain ; name="scsi.c"; charset=us-ascii Content-Description: scsi.c Content-Disposition: attachment; filename="scsi.c" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/scsiio.h> #include <sys/cdio.h> #ifndef EXIT_FAILURE #define EXIT_FAILURE -1 #endif /* SCSI command codes */ #define SC_TEST_UNIT_READY 0x00 #define SC_INQUIRY 0x12 #define SC_BLANK 0xA1 #define SC_PLAY_AUDIO 0xA5 #define SC_PLAY_AUDIO_TRACK_INDEX 0x48 #define SC_PLAY_TRACK_RELATIVE 0x49 #define SC_GROUP0_LEN 6 #define SC_GROUP1_LEN 10 #define SC_GROUP2_LEN 10 #define SC_GROUP3_LEN 0 /* reserved */ #define SC_GROUP4_LEN 0 /* reserved */ #define SC_GROUP5_LEN 12 #define SC_GROUP6_LEN 0 /* vendor */ #define SC_GROUP7_LEN 0 /* vendor */ /* Identify the bus, target, and lun associated with the file descriptor, or return -1 if the attached device is not a SCSI device. */ int scsi_identify(int fd, int btl[3]) { struct scsi_addr saddr; if (ioctl(fd, SCIOCIDENTIFY, &saddr) < 0) { perror("getting SCSI address"); return -1; } #ifdef __NetBSD__ if (saddr.type != TYPE_SCSI) { printf("not a SCSI address\n"); return -1; } btl[0] = saddr.addr.scsi.scbus; btl[1] = saddr.addr.scsi.target; btl[2] = saddr.addr.scsi.lun; #else btl[0] = saddr.scbus; btl[1] = saddr.target; btl[2] = saddr.lun; #endif return 0; } /* Reset the specified device. */ int scsi_reset(int fd) { if (ioctl(fd, SCIOCRESET, 0) < 0) { perror("reseting SCSI device\n"); return -1; } return 0; } /* Turn debugging on for the specified device. */ int scsi_debug(int fd, int level) { int cmd = 0; if (level > 0) cmd = SC_DB_CMDS; if (ioctl(fd, SCIOCDEBUG, cmd) < 0) { perror("setting SCSI debug level"); return -1; } return 0; } static int scsi_command(int fd, scsireq_t *req) { int status = 0; req->flags |= SCCMD_ESCAPE; /* We set the SCSI cmd len */ if (req->timeout == 0) req->timeout = 1000; /* 1 sec */ bzero(req->sense, sizeof(req->sense)); req->senselen = sizeof(req->sense); req->senselen_used = 0; req->status = 0; req->retsts = 0; req->error = 0; printf("sending SCSI command"); { int i; for (i = 0; i < req->cmdlen; i++) printf(" %02x", req->cmd[i]); } printf("\n"); fflush(stdout); if (ioctl(fd, SCIOCCOMMAND, req) < 0) { perror("sending SCSI command"); return -1; } switch (req->retsts) { case SCCMD_OK: break; case SCCMD_TIMEOUT: printf("scsi timeout\n"); status = -1; break; case SCCMD_BUSY: printf("scsi device busy\n"); status = -1; break; case SCCMD_SENSE: printf("scsi check sense\n"); status = -1; break; default: case SCCMD_UNKNOWN: printf("unknown scsi status %d\n", req->retsts); status = -1; } return status; } /* +=====-========-========-========-========-========-========-========-========+ | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |Byte | | | | | | | | | |=====+=======================================================================| | 0 | Operation code (00h) | |-----+-----------------------------------------------------------------------| | 1 | Logical unit number | Reserved | |-----+-----------------------------------------------------------------------| | 2 | Reserved | |-----+-----------------------------------------------------------------------| | 3 | Reserved | |-----+-----------------------------------------------------------------------| | 4 | Reserved | |-----+-----------------------------------------------------------------------| | 5 | Control | +=============================================================================+ */ int scsi_test_unit_ready(int fd) { scsireq_t req; int status = 0; bzero(&req, sizeof(req)); req.cmd[0] = SC_TEST_UNIT_READY; req.cmdlen = SC_GROUP0_LEN; status = scsi_command(fd, &req); if (status == 0) { int asc = req.sense[12]; int ascq = req.sense[13]; printf("test unit ready: sense ASC=%x ASCQ=%x\n", asc, ascq); } return status; } /* Table 44 - INQUIRY command +=====-========-========-========-========-========-========-========-========+ | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |Byte | | | | | | | | | |=====+=======================================================================| | 0 | Operation code (12h) | |-----+-----------------------------------------------------------------------| | 1 | Logical unit number | Reserved | EVPD | |-----+-----------------------------------------------------------------------| | 2 | Page code | |-----+-----------------------------------------------------------------------| | 3 | Reserved | |-----+-----------------------------------------------------------------------| | 4 | Allocation length | |-----+-----------------------------------------------------------------------| | 5 | Control | +=============================================================================+ */ int scsi_inquiry(int fd, char buffer[96]) { scsireq_t req; bzero(&req, sizeof(req)); bzero(buffer, 96); req.cmd[0] = SC_INQUIRY; req.cmd[4] = 96; req.cmdlen = SC_GROUP0_LEN; req.flags = SCCMD_READ; req.databuf = buffer; req.datalen = 96; req.timeout = 10 * 1000; if (scsi_command(fd, &req) < 0) return -1; return 0; } int scsi_quick_erase(int fd) { scsireq_t req; bzero(&req, sizeof(req)); req.cmd[0] = SC_BLANK; req.cmd[1] = 1; /* code 1 blank type -- quick erase */ req.cmdlen = SC_GROUP5_LEN; req.timeout = 240 * 1000; if (scsi_command(fd, &req) < 0) return -1; return 0; } static int scsi_play_audio_track(int fd, int track, int index) { #if 0 scsireq_t req; bzero(&req, sizeof(req)); req.cmd[0] = SC_PLAY_AUDIO_TRACK_INDEX; req.cmd[4] = track; req.cmd[5] = index; req.cmd[7] = track + 1; req.cmd[8] = index + 1; req.cmdlen = SC_GROUP1_LEN; req.timeout = 240 * 1000; if (scsi_command(fd, &req) < 0) return -1; return 0; #else struct ioc_play_track play; struct ioc_toc_header tochdr; if (ioctl(fd, CDIOREADTOCHEADER, &tochdr) < 0) { perror("reading CD TOC header"); return -1; } printf("disk contains %d tracks\n", tochdr.ending_track - tochdr.starting_track + 1); play.start_track = track; play.start_index = index; play.end_track = tochdr.ending_track; play.end_index = 99; if (ioctl(fd, CDIOCSTART) < 0) { perror("starting CD"); return -1; } sleep(30); #if 0 if (ioctl(fd, CDIOCPLAYTRACKS, &play) < 0) { perror("playing tracks"); return -1; } #endif return 0; #endif } int scsi_play_audio(int fd) { unsigned long tlen = 650 * 1024 * 1024; /* whole disk */ scsireq_t req; bzero(&req, sizeof(req)); req.cmd[0] = SC_PLAY_AUDIO; req.cmd[6] = (tlen >> 24) & 0xff; req.cmd[7] = (tlen >> 16) & 0xff; req.cmd[8] = (tlen >> 8) & 0xff; req.cmd[9] = tlen & 0xff; req.cmdlen = SC_GROUP5_LEN; req.timeout = 240 * 1000; if (scsi_command(fd, &req) < 0) return -1; return 0; } static void print_field(char *s, int l1, int l2) { int i; for (i = l1; i <= l2; i++) putchar(s[i]); } /* Table 45 - Standard INQUIRY data format +=====-========-========-========-========-========-========-========-========+ | Bit| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |Byte | | | | | | | | | |=====+==========================+============================================| | 0 | Peripheral qualifier | Peripheral device type | |-----+-----------------------------------------------------------------------| | 1 | RMB | Device-type modifier | |-----+-----------------------------------------------------------------------| | 2 | ISO version | ECMA version | ANSI-approved version | |-----+-----------------+-----------------------------------------------------| | 3 | AENC | TrmIOP | Reserved | Response data format | |-----+-----------------------------------------------------------------------| | 4 | Additional length (n-4) | |-----+-----------------------------------------------------------------------| | 5 | Reserved | |-----+-----------------------------------------------------------------------| | 6 | Reserved | |-----+-----------------------------------------------------------------------| | 7 | RelAdr | WBus32 | WBus16 | Sync | Linked |Reserved| CmdQue | SftRe | |-----+-----------------------------------------------------------------------| | 8 | (MSB) | |- - -+--- Vendor identification ---| | 15 | (LSB) | |-----+-----------------------------------------------------------------------| | 16 | (MSB) | |- - -+--- Product identification ---| | 31 | (LSB) | |-----+-----------------------------------------------------------------------| | 32 | (MSB) | |- - -+--- Product revision level ---| | 35 | (LSB) | |-----+-----------------------------------------------------------------------| | 36 | | |- - -+--- Vendor-specific ---| | 55 | | |-----+-----------------------------------------------------------------------| | 56 | | |- - -+--- Reserved ---| | 95 | | |=====+=======================================================================| | | Vendor-specific parameters | |=====+=======================================================================| | 96 | | |- - -+--- Vendor-specific ---| | n | | +=============================================================================+ */ static int print_inquiry_data(char buffer[96]) { int i; int dt; static char* device_type[] = { "direct-access", "sequential-access", "printer device", "processor device", "write-once device", "CD-ROM", "scanner", "optical memory", "medium changer", "communications" }; printf("INQUIRY buffer:"); for (i = 0; i < 96; i++) { unsigned char uc = buffer[i]; printf("%c0x%x", i % 8 == 0 ? '\n' : ' ', (int) uc); } printf("\n"); dt = buffer[0] & 0x1f; printf("SCSI device: %s ", dt < 10 ? device_type[dt] : "unknown"); print_field(buffer, 8, 15); printf(" revision "); print_field(buffer, 32, 35); printf("\n"); return 0; } int main(int argc, char**argv) { int fd; int arg; char* fn = "/dev/cd0c"; int scsiaddr[3]; int status = 0; fd = open(fn, O_RDWR, 0); if (fd < 0) { perror("opening SCSI device"); exit(EXIT_FAILURE); } if (scsi_identify(fd, scsiaddr) < 0) { printf("failed to identify SCSI device\n"); exit(EXIT_FAILURE); } printf("bus%d target%d lun%d\n", scsiaddr[0], scsiaddr[1], scsiaddr[2]); if (scsi_test_unit_ready(fd) < 0) { printf("unit failed to test ready\n"); exit(EXIT_FAILURE); } for (arg = 1; arg < argc; arg++) { if (strcmp("--quick-erase", argv[arg]) == 0) { status = scsi_quick_erase(fd); } else if (strcmp("--play-audio", argv[arg]) == 0) { int use_track = 0; int track = 1; int index = 1; if (argc > (arg + 1)) { track = atoi(argv[++arg]); use_track = 1; if (argc > (arg + 1)) index = atoi(argv[++arg]); } if (use_track) { printf("playing track %d index %d\n", track, index); status = scsi_play_audio_track(fd, track, index); } else status = scsi_play_audio(fd); } else if (strcmp("--inquiry", argv[arg]) == 0) { char buffer[96]; scsi_inquiry(fd, buffer); print_inquiry_data(buffer); } else if (strcmp("--debug", argv[arg]) == 0) { scsi_debug(fd, 1); } else { printf("unrecognized command %s\n", argv[arg]); fflush(stdout); exit(EXIT_FAILURE); } } if (status != 0) { printf("resetting SCSI unit\n"); scsi_reset(fd); } exit(0); } --==_Exmh_18900079500 Content-Type: text/plain; charset=us-ascii ------------------------------------- David Deaven deaven@execpc.com http://www.execpc.com/~deaven --==_Exmh_18900079500-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199812221214.GAA16013>