void download_firmware() { SCSI *dl; int w, key, fh, choice, org_asa, new_asa, n= 0, off= 0; unsigned bufsize= 8*1024, rv; char *filename, *p; long l, j, i, jj, offset; if (!is_seagate_disk(inq)) message("WARNING !rn" "rn" "Download firmware is only tested with Seagate disk drives."); filename= calloc(1, 128); if (!filename) { printf("Error allocating %u bytes of memoryn", 128); exit(0); } strcpy(filename, config->download_file); key= edit_string_window(filename, 70, "Enter firmware file to download"); if (key== KEY_ENTER) { fh= open(filename, O_RDONLY|O_BINARY); if (fh!= -1) { w= window_create(-1, 9, 60, 18, BLUEs.host_adapter= inq->s.host_adapter; dl->s.target_id= inq->s.target_id; dl->s.lun= inq->s.lun; dl->s.scsi_command[0]= 0x3B; if (off== 0) { p= farmalloc(l); if (p== NULL) { message("Error allocating %lu bytes", l); einde(-1); } dl->s.scsi_command[1]= 0x05; dl->s.data_buffer= p; dl->s.data_buffer_length= l; } else dl->s.scsi_command[1]= 0x07; *(unsigned long *)&dl->s.scsi_command[5]= swaplong(dl->s.data_buffer_length); if (off== 1) { offset= 0; j= l / bufsize; jj= l % bufsize; gotoxy(1,3); cprintf("%lu blocks of %uK and %lu bytesrn", j, (bufsize >> 10), jj); cprintf("Block:"); for (i= 0; i s.data_buffer, bufsize, &rv); *(unsigned long *)&dl->s.scsi_command[2]= swaplong(offset); if (rv== bufsize) scsi_execute(dl, 1); else { message("Error while reading firmware file"); einde(-1); } gotoxy(8,4); cprintf("%lu", i); offset+= rv; } if (jj) { gotoxy(20,3); _dos_read(fh, dl->s.data_buffer, jj, &rv); *(unsigned long *)&dl->s.scsi_command[2]= swaplong(offset); *(unsigned long *)&dl->s.scsi_command[5]= swaplong(rv); if (rv== jj) scsi_execute_bg(dl); else { message("Error while reading firmware file"); einde(-1); } gotoxy(26,4); cprintf("%u", i); offset+= rv; } } else { cprintf("Reading file %s, %lu KB", filename, l >> 10); rv= file_read_into_memory(fh, p, l); if (rv) { message("Error while reading firmware file"); einde(-1); } scsi_execute_bg(dl); } gotoxy(1,4); clreol(); cprintf("Download status :"); n= 0; while(dl->s.status== 0) { gotoxy(18,4); putch(wiekje[n++]); if (!wiekje[n]) n= 0; gotoxy(19,4); cprintf("%-10.10s", aspi_status_name(dl->s.status)); delay(250); } gotoxy(18,4); putch(' '); gotoxy(19,4); cprintf("%-10.10s", aspi_status_name(dl->s.status)); if (dl->s.status!= 1) { gotoxy(1,5); print_sense_info_short(dl); } else { gotoxy(1,6); cprintf("Waiting for unit"); wait_unit_ready(inq); new_asa= seagate_asa_level(inq); gotoxy(1,6); clreol(); cprintf("New ASA level is ASA%u", new_asa); if (org_asa!= new_asa) { message("You upgraded your drive to a newrn" "ASA level, drive needs low level format !rn" /*大家注意这点,升级是有风险的,这个信息只是其中一个很小的风险,由于ASA级别的改变,需要你低级格式化硬盘,哈哈数据没啦! SEAGATE厂的ASA为2。其他计算机大厂的ASA有的为0有的为1……,自己找些资料参考吧。 */ "rn" "%s", fortune(fun_message)); } } if (off== 0) { dl->s.data_buffer= NULL; dl->s.data_buffer_length= 0; farfree(p); } scsi_destroy(dl); pause(); } } close(fh); window_destroy(w); strcpy(config->download_file, filename); cfg_save(); } else message("Error opening file %snr->%s", filename, sys_errlist[errno]); } |
.MODEL large, C .DATA .CODE extrn AspiEntryPoint:dword public SRBexec SRBexec PROC C, segm:WORD, ofs:WORD mov ax, segm push ax mov ax, ofs push ax call DWORD PTR [AspiEntryPoint] add sp, 4 ret SRBexec ENDP public swaplong swaplong PROC C, long1,long2:WORD mov ax, long2 xchg al, ah mov dx, long1 xchg dl, dh ret swaplong ENDP public swapint swapint PROC C, int1:WORD mov ax, int1 xchg al, ah ret swapint ENDP end |
/*-------------------------------------------------------------------------- Filename : sgdskfl.c Abstract : SCSI Generic Disk Firmware Load tool Operation System: Linux 2.2 or greater Copyright ? Intel Corporation 2001 Author: Andy Cress ----------- Change History ----------------------------------------------- 05/01/01 v0.70 ARCress created 07/17/01 v0.91 ARCress added code to download servo also added write_buffers code to do multi-part dl. 08/08/01 v0.92 ARCress fixed write_buffers logic for IBM disks. 09/05/01 v0.93 ARCress message cleanup 09/28/01 v0.94 ARCress turn off sg_debug in afterdl 10/15/01 v0.95 ARCress fixed IBM chunk size 10/30/01 v1.0 ARCress cleanup includes & indent -kr 11/09/01 v1.0 ARCress enlarged devstat2 from 80 to 120 for overrun 11/14/01 v1.0 ARCress added default directory for image files. 04/11/02 v1.1 ARCress path changes for log & image files, set do_numeric=1 default 05/08/02 v1.3 ARCress tune sg_debug level down to 5 by default 08/15/02 v1.4 ARCress moved common subroutines to sgcommon added more usage messages 09/03/02 v1.5 ARCress streamline display for errors in get_scsi_info 01/08/03 v1.6 ARCress include Quantum in getimage:fscanmodel. ----------- Des cription -------------------------------------------------- sgdskfl Sequence of events for this utility: * List each device on the system with firmware versions. * User selects a device for firmware load (automatic if using -m) * Read the firmware image file for the selected disk and verify that it is valid. * Verify that the disk is present and ready * Close all open files, flush the adapter, sync any data to the SCSI disks. * Write the firmware image to the disk using a 'write buffer' SCSI command with large reserved buffer or scatter/gather. * Wait 5 (or specified number) seconds * Verify that the disk comes ready again using SCSI test_unit_ready commands, and start_unit or scsi_reset to recover if not. * If the '-m' option was used, repeat writing the firmware for each disk of this model. sgdskfl [-e -m diskmodel -f imagefile -t secdelay -x] Options: -e Do not write to any files. Usually a log file (sgdskfl.log) is created and written to, up until the firmware download begins on root. -m Automatically download all drives that match this model string. Note that this option will initiate a reboot after it is done, unless option u is also specified. -f Specify this filename for the firmware image. Normally, this option is not used and the filename is formed using the first 8 characters of the model, with the ".lod" extension. For example: "st39140w.lod". Note that this utility uses the raw firmware image without any added headers. -t Specifies the number of seconds to delay after the firmware is written and the program attempts to test if the unit is ready again. Default is 10 seconds. -r Recover a non-ready drive by updating its firmware. Don't test if the drive is ready or not. -x Outputs extra debug messages -d Specify a unix device name ----------------------------------------------------------------------------*/ /*------------------------------------------------------------------------- Copyright ? 2002, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: a.. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. b.. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. c.. Neither the name of Intel Corporation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include "sgsub.h" #include "sgcommon.h" /* External Functions prototypes */ extern void setbuf(FILE * stream, char *buf); extern int errno; extern char fdebugsub; /* used in sgsub.c */ extern FILE *dbgout; /* used in sgsub.c */ #define EBUFF_LEN 80 #define MAX_ERRORS 4 /* Global data definitions */ char progver[] = "1.6"; /* program version */ char *progname = "sgdskfl"; /* program name */ char logfile[] = "/var/log/sgdskfl.log"; /* log filename */ char fwsufx[] = ".lod"; /* suffix for firmware image filenames */ char model[20] = ""; /* default model string */ char fsetfile = 0; char fwfile[20] = "default"; /* default firmware filename (8.lod) */ char defdir[30] = "/usr/share/scsirastools/"; /*default directory for fw files*/ char devname[80] = "/dev/sda"; /* UNIX device name (w path) */ char svfile[20] = "default"; /* default servo filename (8.tms) */ int sdelay = 10; /* num sec to delay before TUR */ FILE *fdlog = NULL; /* log file des criptor */ FILE *fdmsg; /* file des criptor for messages */ char fautomodel = 0; /* =1 to automatically do all of a model */ char filesok = 1; /* =1 if ok to write to files */ char fdebug = 0; /* =1 for debug messages */ char fdoreset = 0; /* =1 if need to do reset for this drive */ char flogopen = 0; /* =1 if log file is open */ char fnotur = 0; /* =1 to not try TUR */ char fdevname = 0; /* =1 if device name specified */ int do_numeric = 1; /* NUMERIC_SCAN_DEF; */ uchar sense_buffer[80]; /* buffer for sense data */ char output[132]; /* message output buffer */ char output2[80]; /* extra message output buffer */ uchar devstat[80]; /* used for inquiry & device status */ uchar devstat2[120]; /* used for Seagate inquiry2 & Mylex stat */ uchar disk_buffer[0x200]; /* 512 bytes, used for misc scsi data */ uchar *image_buffer; /* malloc'd firmware image buffer */ uchar *servo_buffer; /* malloc'd servo buffer */ int idev = 0; int ndev = 0; DEVLIST_TYPE devlist[32]; char *devtype_array[11] = { "Disk ", "Tape ", "Printer", "Procesr", "WORM ", "CD-ROM ", "Scanner", "Optical", "Med Chg", "Comm ", "Unknown" }; /* Local subroutines */ int writeimage(int idx, uchar * imgbuf, ulong len, char fservo); ulong getimage(int idx, uchar ** pbuf, char fservo); int beforedl(int idx, int *pnumrdy); int afterdl(void); int main(int argc, char **argv) { int i, c, idx; char response = 0; ulong size; /* size of fw */ ulong size_sv; /* size of servo */ int runl; short sts, rc; ulong ltime1; char fname[64]; char ebuff[EBUFF_LEN]; int sg_fd; int flags; int res, k; int eacces_err = 0; int num_errors = 0; DEVFS_LIST devfs_components = {0,0,0,0,0}; // progname = argv[0]; fdmsg = stdout; /* set default fdmsg */ while ((c = getopt(argc, argv, "enxrf:m:t:d:?")) != EOF) switch ? { case 'e': filesok = 0; break; case 'x': fdebug = 1; break; case 'r': fnotur = 1; break; case 'n': do_numeric = 0; break; case 'f': strcpy(fwfile, optarg); fsetfile = 1; break; case 'm': fautomodel = 1; /* automatically do all of this model */ strcpy(model, optarg); break; case 't': sdelay = atoi(optarg); /* time to delay */ break; case 'd': strcpy(devname, optarg); /* specify a unix device name */ fdevname = 1; break; case '?': default: printf("Usage: %s [-m diskmodel -f imagefile -t secdelay -enrx]n", progname); printf(" -m Automatically download all drives that match this model stringn"); printf(" -f Specify filename for firmware image instead of defaultn"); printf(" -t Time in seconds to delay after the firmware is written, default 10n"); printf(" -n Turn off Numeric, use alpha device names insteadn"); printf(" -e Do not write to any files, so don't use the log filen"); printf(" -r Recover a non-ready drive by updating its firmwaren"); printf(" -x Outputs extra debug messagesn"); exit(1); } /* only run this as superuser */ i = geteuid(); if (i > 1) { printf("Not superuser (%d)n", i); exit(1); } /* check for run-level 1 */ { runl = 1; /* how to check this? */ if (fdebug) { /*DEBUG*/ printf("sdelay = %d secn", sdelay); printf("run-level = %dn", runl); } } if (runl != 1) { /* show warning if not run level 1 */ printf ("Warning: Make sure disks are inactive during firmware downloadn"); // dont exit, just give a warning. } /* open log file */ if (filesok) fdlog = fopen(logfile, "a+"); if (fdlog == NULL) { flogopen = 0; filesok = 0; fdlog = stderr; } else { /* logfile open successful */ flogopen = 1; time((time_t *) & ltime1); fprintf(fdlog, "n--- %s v%s log started at %s", progname, progver, ctime((long *) fprintf(fdlog, "model: %sn", model); fprintf(fdlog, "fw file: %sn", fwfile); } fdebugsub = fdebug; dbgout = fdlog; /* loop to display disk choices and do downloads */ while (1) { /* display header */ printf("n"); printf(" %s utility v%s for SCSI disksn", progname, progver); printf (" ******************************************n"); if (flogopen) printf("Log file %s is open, debug=%dn", logfile, fdebug); printf ("nNum Name [bus:ch:id:lun] Type Vendor Device_Model FW__ Serial#_ Servo___n"); /* get SCSI Device Info */ idev = 0; flags = O_RDWR; /* could use OPEN_FLAG if read-only. */ num_errors = 0; for (k = 0; (k 0) { res = close(sg_fd); if (res vendorid, "SEAGATE", 7) != 0) fservo = 3; /* Seagate tapes use split buffer method 3 */ /* Tecmar, Travan, Wangtek, WangDAT tapes use method 2 */ else fservo = 2; /* use split buffer method 2 */ } else if ( (strncmp ((char *) scsi_inq->vendorid, "IBM", 3) == 0) && (strncmp ((char *) scsi_inq->productid, "ST", 2) != 0)) /* for all IBM disks, except Seagate OEM */ fservo = 4; /* IBM disks use split buffer method X */ else fservo = 0; /* normal, all one buffer */ if (size > 0) { /* flash firmware */ rc = writeimage(i, image_buffer, size, fservo); free(image_buffer); /*allocated in getimage() */ if (fdebug && rc != 0) { showit((char *) disk_buffer); /*writes saved messages */ quit(rc); } } if (size_sv > 0) { /* flash servo */ rc = writeimage(i, servo_buffer, size_sv, 1); free(servo_buffer); /*allocated in getimage() */ } } if (!fautomodel) i = ndev; /* only do one if interactive */ } /*endfor each disk */ rc = afterdl(); } /*endif image ok */ } /*end else index ok */ } /*end else do download */ else { /* response not d or q */ printf("Invalid input [%c], enter 'd' or 'q'.n", response); } if (fautomodel) { /* then done */ if (0) { /* if root is down and likely to hang otherwise, */ printf("Rebooting ...n"); sleep(3); // /* do reboot without shutdown */ } else quit(0); /* normal exit, successful */ } else { /* interactive, go to menu again */ do_pause(); } } /*end while(1) */ } /*end main() */ ulong getimage(int idx, uchar ** pbuf, char fservo) { ulong filsz; FILE *fdimg; struct stat statbuf; struct SCSI_INQUIRY *scsi_inq; char modelx[20]; char *filenm; char fullfilenm[80]; char *buf; int i, rc; *pbuf = NULL; scsi_inq = (struct SCSI_INQUIRY *) devlist[idx].inq; if (fautomodel) strncpy(modelx, model, strlen(model)); else strncpy(modelx, (char *) scsi_inq->productid, 16); for (i = 0; i vendorid); showit(output); } if (!fsetfile) { /* build the default filename */ for (i = 0; i vendorid, "SEAGATE", 7) == 0) { if (modelx[7] == 'W') modelx[7] = 'N'; /*always match with narrow */ modelx[8] = 0; /* truncate to 8 chars for search */ fscanmodel = 1; } else if (strncmp((char *) scsi_inq->vendorid, "IBM", 3) == 0) fscanmodel = 1; else if (strncmp((char *) scsi_inq->vendorid, "MAXTOR", 6) == 0) fscanmodel = 1; else if (strncmp((char *) scsi_inq->vendorid, "QUANTUM", 7) == 0) fscanmodel = 1; /* HITACHI and FUJITSU only have partial model strings to match */ if (fscanmodel) { /* scan image buffer for model(productid) */ /* A variable offset in the file has a list of the target models. */ rc = findmatch(buf, filsz, modelx, strlen(modelx), 1); /*also ignore case */ if (rc == -1) { sprintf(output, "Image does not match model %sn", modelx); showit(output); fclose(fdimg); free(buf); return (0); /* size = 0 */ } if (fdebug) { sprintf(output, "Image file matches model %sn", modelx); showit(output); } } /*endif scanmodel */ } /*endif not servo */ *pbuf = buf; fclose(fdimg); return (filsz); } /*end getimage() */ int write_buffers(int sgfd, uchar * buf, ulong len, uchar fservo) { int sts; ulong j, sz_left; ulong max_chunk; uchar save_mode; uchar bufid; uchar ebuf[20]; if (fservo >= 2) { if (fservo == 3) { /* Seagate tapes */ max_chunk = 0x4000; save_mode = 0x07; } else if (fservo == 2) { /* other tapes */ max_chunk = 0x8000; save_mode = 0x05; } else // if (fservo == 4) { /* IBM disks */ { max_chunk = 0x8000; /* get this from mode page C7, bytes 16-18 */ save_mode = 0x05; if (fdebug) fprintf(fdlog, "IBM split buffer mode, chunk size = %ldn", max_chunk); j = 0; sz_left = len; bufid = 0; while (sz_left > max_chunk) { /* Note that it uses mode 05 for every chunk, not just last one */ sts = write_buffer(sgfd, &buf[j], max_chunk, save_mode, bufid); if (sts != 0) { unsigned int k, a, q; int rc; rc = get_sense(sts, ebuf); k = ebuf[2] & 0x0f; /*Sense Key */ a = ebuf[12]; /*ASC*/ q = ebuf[13]; /*ASCQ*/ sprintf(output, "wb sense error: %x/%x/%xn", k, a, q); showit(output); if (k == 03 && a == 0x30) printf("Overlay upload errorn"); else if ((k == 2 || k == 3 || k == 4) && (a == 0x40 && q max_chunk) { sts = write_buffer(sgfd, &buf[j], max_chunk, 0x04, bufid); if (sts != 0) return (sts); sz_left -= max_chunk; j += max_chunk; } sts = write_buffer(sgfd, &buf[j], sz_left, save_mode, bufid); } /*endif split buffer scheme */ else { /* fservo == 0, or fservo == 1 */ /* Send it all as one big buffer */ sts = write_buffer(sgfd, buf, len, 0x05, 0L); } return (sts); } /* end write_buffers() */ int writeimage(int idx, uchar * imgbuf, ulong len, char fservo) { int sts; int devfd; int isave; ulong ltime, ltime1, ltime2; ulong ltime3; int i, rc, rcdl; int k, a, q; char *tag; uchar ch, dv; isave = idx; rcdl = 0; /* Download firmware to this disk */ { rcdl = 0; fdoreset = 0; if (!fautomodel) idx = isave; /* only do selected disk */ devfd = devlist[idx].sgfd; ch = devlist[idx].chn; dv = devlist[idx].tgt; if (devlist[idx].fdoit == 1) { if (fautomodel) { /* Sometimes next device may have a unit attention/reset check * condition pending, so clear that first before the write_buffer. */ sts = test_unit_ready(devfd, 0); if (fdebug) fprintf(fdlog, "Extra test_unit_ready sts = %xn", sts); } time((time_t *) & ltime1); // get the start time /* start the firmware download */ if (fservo == 1) tag = "Servo"; else tag = "Firmware"; sprintf(output, "Downloading %s image to disk %d %s", tag, idx, ctime((long *) // ctime outputs a 'n' at end showit(output); sts = write_buffers(devfd, imgbuf, len, fservo); if (sts) { rcdl = sts; sprintf(output, "[%d] Error %d in writing buffern", idx, sts); showit(output); // fdlog closed if (fdebug || !fautomodel) { return (rcdl); // (only if debug on) } } if (fautomodel && rcdl != 0) { /* Save error for logging later */ sprintf(output, "[%d] %s download error, status = 0x%xn", idx, tag, rcdl); strcat((char *) disk_buffer, output); /* Try to restart the drive, even if the download failed. */ return (rcdl); /*skip to next one if error */ } // Test if Unit is Ready again sprintf(output, "Waiting for disk to come ready again "); showit(output); sleep(sdelay); /* wait for the drive to reset and come ready */ for (i = 0; i productid, 8); model[8] = 0; /*stringify */ } for (idx = 0; idx productid, 8) == 0) { /* do only ones of the same disk product id */ sts = test_unit_ready(sgfd, 0); if (sts == SCHECK_CND) { /* not ready initially, try to make it ready */ i = get_sense(sts, sense_buffer); k = sense_buffer[2] & 0x0f; /*Sense Key */ a = sense_buffer[12]; /*ASC*/ q = sense_buffer[13]; /*ASCQ*/ if (k == 2 && a == 4 && q == 2) { /* 02-04-02 means it needs a start command, so issue it. */ sts = start_unit(sgfd); if (fdebug) { /*DEBUG*/ printf("nStart Unit: sts=%d, ", sts); if (sts == SCHECK_CND) { rc = get_sense(sts, sense_buffer); printf("sense data: %x %x %xn", sense_buffer[2] & 0x0f, sense_buffer[12], sense_buffer[13]); } } } /*endif 02-04-02 */ sts = test_unit_ready(sgfd, 1); /* try again */ } if (sts) { sprintf(output, "[%d] Error %d from Test Unit Readyn", idx, sts); showit(output); devlist[idx].fdoit = 0; if (fnotur) { devlist[idx].fdoit = 1; nrdy++; } } else { devlist[idx].fdoit = 1; sprintf(output, "Device [%d] is ready for downloadn", idx); showit(output); nrdy++; /* number ready to download */ } } else devlist[idx].fdoit = 0; /* not same product id */ if (!fautomodel) idx = ndev; /* end loop */ } /* end for devlist TUR loop */ *pnumrdy = nrdy; /* set return value */ if (nrdy == 0) { sprintf(output, "There are no ready devices for model %s.n", model); showit(output); return (sts); } else { if (nrdy > 1) pl = "s"; else pl = ""; sprintf(output, "Starting download process for %d disk%s.n", nrdy, pl); showit(output); } closelog(); /* sets flogopen to false */ filesok = 0; /* allows files to be opened again */ fflush(fdmsg); /* flush stdout/stderr for messages */ setbuf(fdmsg, NULL); /* set for unbuffered writes */ sync(); sync(); /* write all UNIX buffers to disk */ sleep(2); /* can't have any more disk IOs from here on */ if (0) { /* fumntroot) *//* unmount root by default, skip it if user says not to. */ fprintf(fdmsg, "Unmounting root ..."); // rc = uadmin(4, 128, 0); /* unmount root fs */ if (rc == 0) fprintf(fdmsg, "donen"); else fprintf(fdmsg, "rc = %dn", rc); // frootdown = 1; } /* Take all drives offline first if specified. */ disk_buffer[0] = 0; /* used for messages later */ return (rcdl); } /*end beforedl() */ int afterdl(void) { int i, sts; sts = 0; /* Bring all drives online again if raid */ /* done, all drives should be ready now */ filesok = 1; /* allows files to be opened again */ showit((char *) disk_buffer); /* writes saved messages */ for (i = 0; i 0) { sts = set_sg_debug(devlist[I.sgfd, 0); if (sts && fdebug) fprintf(fdlog, "[%d] cant clear debug flag, sts=%d errno=%dn", i, sts, errno); close(devlist[I.sgfd); /*opened in beforedl() */ devlist[I.sgfd = 0; } } return (sts); } /*end afterdl() */ /* end sgdskfl.c */ |
int glist(SCSI *sp) { SCSI *s; int al= 8, retval= -1, rv, format; char format_mask[]= { 0x00, 0x04, 0x05, 0 }; int format_size[]= { 4,8,8,0 }; s= scsi_init(al); idcpy(s, sp); s->s.scsi_command[0]= 0x37; s->s.scsi_command[2]= 0x08; *(unsigned int *) &s->s.scsi_command[7]= swapint(al); for (rv= 0, format= 0; format s.scsi_command[2]&= 0xf8; s->s.scsi_command[2]|= format_mask[format]; rv= scsi_execute(s, 0); } format--; if (rv== 1) { retval= swapint(*(unsigned int *)&s->s.data_buffer[2]) format_size[format]; } scsi_destroy(s); return(retval); } |