📄 rzdisk.c
字号:
int baddata; off_t offset; int retries = 5; int i; char prodid[17]; bzero((char *)&inq, sizeof(inq)); if(execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq) != SUCCESS) { geterror(); return; } else { for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * REASSIGN BLOCK not supported on RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) { printf("\nReassign Block unsupported on device (%s).\n", rzdisk); return; } } /* * Read the data from the bad block before doing * the reassign and save it in a temporary buffer. * Set "baddata" flag if we could not read the data * in the bad block. */ bzero(buffer, 512); offset = lbn * 512; while(retries--) { lseek(rzdev, offset, 0); if(read(rzdev, buffer, 512) == -1) baddata = 1; else { baddata = 0; break; } } bzero((char *)&rp, sizeof(rp)); rp.rp_lbn3 = ((lbn >> 24) & 0xff); rp.rp_lbn2 = ((lbn >> 16) & 0xff); rp.rp_lbn1 = ((lbn >> 8) & 0xff); rp.rp_lbn0 = ((lbn >> 0) & 0xff); rp.rp_header.defect_len1 = 0; rp.rp_header.defect_len0 = 4;reassign: printf("\nReassigning bad block (%d) on device (%s).\n",lbn,rzdisk); if(execute_rzcmd(SCSI_REASSIGN_BLOCK, (char *)&rp) != SUCCESS) { geterror(); return; } /* * Write the saved data from the temporary buffer * back to the newly reassigned block. */ lseek(rzdev, offset, 0); if(write(rzdev, buffer, 512) == -1) goto reassign; /* * Inform user if the data is (GOOD) or (BAD). */ if(baddata) printf("\nThe data in the reassigned block is (BAD).\n"); else printf("\nThe data in the reassigned block is (GOOD).\n");}scan_for_bad_blocks(lbn,length)int lbn;int length;{ int modval,i; int lastblk,part,badlbn; char cpart; struct pt pt; int err; bzero((char *)&vp, sizeof(vp)); if(execute_rzcmd(DIOCGETPT, (char *)&pt) != SUCCESS) { printf("\nCannot get partition table from device (%s).\n", rzdisk); return; } cpart = rzdisk[strlen(rzdisk) - 1]; part = cpart - 'a'; lastblk = pt.pt_part[part].pi_blkoff + pt.pt_part[part].pi_nblocks; if(lbn < 0 || lbn > lastblk) { printf("\nInvalid LBN (%d) entered for device (%s).\n", lbn, rzdisk); printf("\nValid LBN range for device (%s) is [%d-%d].\n", rzdisk, pt.pt_part[part].pi_blkoff, pt.pt_part[part].pi_nblocks); return; } lbn = lbn + pt.pt_part[part].pi_blkoff; if(length == -1) length = lastblk - lbn; else if((length + lbn) > lastblk) { printf("\nInvalid length (%d) entered for device (%s).\n", length, rzdisk); printf("\nLength plus LBN cannot exceed (%d) for device (%s).\n", lastblk, rzdisk); return; } printf("\nScanning for bad blocks on device (%s).\n",rzdisk); printf("\nBlock range being scanned is [%d-%d].\n\n", lbn, lbn+length-1); while(length != 0) { vp.vp_lbn = (u_long)lbn; modval = lbn % 30000; if(length > 30000) { vp.vp_length = (u_short) (30000 - modval); length -= (30000 - modval); lbn += (30000 - modval); } else { vp.vp_length = (u_short) length; length -= length; lbn += length; } printf("Scanning blocks [%d-%d]\n", vp.vp_lbn,(vp.vp_length+vp.vp_lbn-1));restart_scan: if(execute_rzcmd(SCSI_VERIFY_DATA, (char *)&vp) != SUCCESS) { err = geterror(); badlbn = infobyte; if(err == FATAL_ERROR) break; else if(err == SOFT_ERROR) { if(asc == 0x18) printf("\tRecoverable data error with ECC"); else printf("\tRecoverable data error with RETRIES"); printf(" at LBN (%d)\n", badlbn); } else if(err == HARD_ERROR) { printf("\tUnrecoverable data error at LBN (%d)", badlbn); printf(" [REASSIGN THE BLOCK]\n"); } vp.vp_length = (vp.vp_length + vp.vp_lbn - badlbn - 1); vp.vp_lbn = badlbn + 1; goto restart_scan; } } printf("\nDone scanning for bad blocks on device (%s).\n",rzdisk);}read_defects(defect_format)u_char defect_format;{ int value,i; char prodid[17]; bzero((char *)&inq, sizeof(inq)); if(execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq) != SUCCESS) { geterror(); return; } else { for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * BLOCK format not supported on RZ22/RZ23 disks. */ if((strncmp(prodid,"RZ22",4) == 0 || strncmp(prodid,"RZ23",4) == 0) && defect_format == BLK_FORMAT) { printf("\nBLOCK format unsupported on device (%s).\n", rzdisk); return; } /* * READ DEFECT DATA not supported on RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) { printf("\nRead Defect Data unsupported on device (%s).\n", rzdisk); return; } } bzero((char *)&dd, sizeof(dd)); rdp.rdp_format = defect_format; rdp.rdp_alclen = sizeof(dd); rdp.rdp_addr = (u_char *)ⅆ printf("\nReading defects from device (%s).\n",rzdisk); if(execute_rzcmd(SCSI_READ_DEFECT_DATA, (char *)&rdp) != SUCCESS) geterror(); else print_defects();}print_defects(){ int i, j, defect_length, ndefects, linecnt; int cylinder, bfi, sector, lba; printf("\nDefect list header:\n"); printf(" Format 0x%02x", dd.dd_header.rdd_hdr.format); if(dd.dd_header.rdd_hdr.mdl) printf(" MDL"); if(dd.dd_header.rdd_hdr.gdl) printf(" GDL"); switch(dd.dd_header.rdd_hdr.format) { case 4: printf(" BYTES\n"); break; case 5: printf(" SECTOR\n"); break; case 6: printf(" VENDOR\n"); break; case 7: printf(" RESERVED\n"); break; default:printf(" BLOCK\n"); break; } defect_length = (dd.dd_header.rdd_hdr.defect_len0 & 0x00ff) + ((dd.dd_header.rdd_hdr.defect_len1 << 8) & 0xff00); if(dd.dd_header.rdd_hdr.format == BLK_FORMAT) ndefects = defect_length / 4; else ndefects = defect_length / 8; printf(" Defect list length %d number of defects %d\n", defect_length, ndefects); i = 0; j = 0; linecnt = 0; while(i < defect_length) { switch (dd.dd_header.rdd_hdr.format) { case 0: case 1: case 2: case 3: lba = ((dd.BLK[j].lba3 << 24) & 0xff000000) + ((dd.BLK[j].lba2 << 16) & 0xff0000) + ((dd.BLK[j].lba1 << 8) & 0xff00) + ((dd.BLK[j].lba0 << 0) & 0xff); printf(" Block %8d\n", lba); i += 4; break; case 4: cylinder = ((dd.BFI[j].cyl2 << 16) & 0xff0000) + ((dd.BFI[j].cyl1 << 8) & 0xff00) + ((dd.BFI[j].cyl0 << 0) & 0xff); bfi = ((dd.BFI[j].bfi3 << 24) & 0xff000000) + ((dd.BFI[j].bfi2 << 16) & 0xff0000) + ((dd.BFI[j].bfi1 << 8) & 0xff00) + ((dd.BFI[j].bfi0 << 0) & 0xff); printf(" Cylinder %6d Head %2d Byte %6d\n", cylinder, dd.BFI[j].head, bfi); i += 8; break; case 5: cylinder = ((dd.PHY[j].cyl2 << 16) & 0xff0000) + ((dd.PHY[j].cyl1 << 8) & 0xff00) + ((dd.PHY[j].cyl0 << 0) & 0xff); sector = ((dd.PHY[j].sector3 << 24) & 0xff000000) + ((dd.PHY[j].sector2 << 16) & 0xff0000) + ((dd.PHY[j].sector1 << 8) & 0xff00) + ((dd.PHY[j].sector0 << 0) & 0xff); printf(" Cylinder %6d Head %2d Sector %4d\n", cylinder, dd.PHY[j].head, sector); i += 8; break; case 6: case 7: return; } ++j; if(++linecnt == 20) { linecnt = 0; if((i < defect_length) && !moreoutput()) return; } }}change_drive_parameters(ask)int ask;{ int setps; int value,i; char prodid[17]; char *ptr; int rz22_rz23_disk = 0; int rrd40_disk = 0; bzero((char *)&inq, sizeof(inq)); if(execute_rzcmd(SCSI_GET_INQUIRY_DATA, (char *)&inq) != SUCCESS) { geterror(); return; } else { for(i=0; i<16; i++) prodid[i] = inq.prodid[i]; prodid[i] = NULL; /* * Can only change pages (1 and 37) for RZ22/RZ23 disks. */ if(strncmp(prodid,"RZ22",4) == 0 || strncmp(prodid,"RZ23",4) == 0) rz22_rz23_disk = 1; /* * Can only change page (1) for the RRD40 disk. */ if(strncmp(prodid,"RRD40",5) == 0) rrd40_disk = 1; } if(ask) goto interactive; printf("\nCHANGING DISK DRIVE PARAMETERS TO DEFAULT VALUES!!!\n"); printstr("\nARE YOU SURE (y/n)? "); if(!confirm()) return; bzero((char *)&ms, sizeof(ms)); ms.ms_pgcode = 0x3f; ms.ms_length = sizeof(ms) - 4; ms.ms_pgctrl = DEFAULT_VALUES; if(execute_rzcmd(SCSI_MODE_SENSE, (char *)&ms) != SUCCESS) { geterror(); return; } bzero((char *)&msc, sizeof(msc)); msc.ms_pgcode = 0x3f; msc.ms_length = sizeof(ms) - 4; msc.ms_pgctrl = CHANGED_VALUES; if(execute_rzcmd(SCSI_MODE_SENSE, (char *)&msc) != SUCCESS) { geterror(); return; } ms.ms_desc.density_code &= msc.ms_desc.density_code; ms.ms_desc.nblks2 &= msc.ms_desc.nblks2; ms.ms_desc.nblks1 &= msc.ms_desc.nblks1; ms.ms_desc.nblks0 &= msc.ms_desc.nblks0; ms.ms_page1.flags &= msc.ms_page1.flags; ms.ms_page1.retry_count &= msc.ms_page1.retry_count; ms.ms_page1.correct_span &= msc.ms_page1.correct_span; ms.ms_page1.head_offset &= msc.ms_page1.head_offset; ms.ms_page1.data_strobe &= msc.ms_page1.data_strobe; ms.ms_page1.recovery_time &= msc.ms_page1.recovery_time; ms.ms_page2.bus_fratio &= msc.ms_page2.bus_fratio; ms.ms_page2.bus_eratio &= msc.ms_page2.bus_eratio; ms.ms_page2.bus_inactive1 &= msc.ms_page2.bus_inactive1; ms.ms_page2.bus_inactive0 &= msc.ms_page2.bus_inactive0; ms.ms_page2.disconn_time1 &= msc.ms_page2.disconn_time1; ms.ms_page2.disconn_time0 &= msc.ms_page2.disconn_time0; ms.ms_page2.conn_time1 &= msc.ms_page2.conn_time1; ms.ms_page2.conn_time0 &= msc.ms_page2.conn_time0; ms.ms_page3.tpz1 &= msc.ms_page3.tpz1; ms.ms_page3.tpz0 &= msc.ms_page3.tpz0; ms.ms_page3.aspz1 &= msc.ms_page3.aspz1; ms.ms_page3.aspz0 &= msc.ms_page3.aspz0; ms.ms_page3.atpz1 &= msc.ms_page3.atpz1; ms.ms_page3.atpz0 &= msc.ms_page3.atpz0; ms.ms_page3.atpv1 &= msc.ms_page3.atpv1; ms.ms_page3.atpv0 &= msc.ms_page3.atpv0; ms.ms_page3.spt1 &= msc.ms_page3.spt1; ms.ms_page3.spt0 &= msc.ms_page3.spt0; ms.ms_page3.bps1 &= msc.ms_page3.bps1; ms.ms_page3.bps0 &= msc.ms_page3.bps0; ms.ms_page3.interleave1 &= msc.ms_page3.interleave1; ms.ms_page3.interleave0 &= msc.ms_page3.interleave0; ms.ms_page3.track_skew1 &= msc.ms_page3.track_skew1; ms.ms_page3.track_skew0 &= msc.ms_page3.track_skew0; ms.ms_page3.cylinder_skew1 &= msc.ms_page3.cylinder_skew1; ms.ms_page3.cylinder_skew0 &= msc.ms_page3.cylinder_skew0; ms.ms_page3.flags &= msc.ms_page3.flags; ms.ms_page4.ncyl2 &= msc.ms_page4.ncyl2; ms.ms_page4.ncyl1 &= msc.ms_page4.ncyl1; ms.ms_page4.ncyl0 &= msc.ms_page4.ncyl0; ms.ms_page4.nheads &= msc.ms_page4.nheads; ms.ms_page4.wprecomp2 &= msc.ms_page4.wprecomp2; ms.ms_page4.wprecomp1 &= msc.ms_page4.wprecomp1; ms.ms_page4.wprecomp0 &= msc.ms_page4.wprecomp0; ms.ms_page4.rwc2 &= msc.ms_page4.rwc2; ms.ms_page4.rwc1 &= msc.ms_page4.rwc1; ms.ms_page4.rwc0 &= msc.ms_page4.rwc0; ms.ms_page4.dsr1 &= msc.ms_page4.dsr1; ms.ms_page4.dsr0 &= msc.ms_page4.dsr0; ms.ms_page4.lzc1 &= msc.ms_page4.lzc1; ms.ms_page4.lzc0 &= msc.ms_page4.lzc0; if(rrd40_disk) setps = 0; else { printstr("\nSAVE THE DEFAULT VALUES ON DISK (y/n)? "); if(confirm()) setps = 1; else setps = 0; } ms.ms_hdr.sense_len = 0; ms.ms_hdr.wp = 0; ms.ms_page1.ps = 0; ms.ms_page2.ps = 0; ms.ms_page3.ps = 0; ms.ms_page4.ps = 0; ms.ms_page37.ps = 0; ms.ms_setps = setps; if(ms.ms_page37.pgcode == 37) ms.ms_length = sizeof(ms) - 4; else ms.ms_length = sizeof(ms) - sizeof(ms.ms_page37) - 4; /* Adjust the length for the RZ22/RZ23 disks */ if(rz22_rz23_disk) { ms.ms_length = ms.ms_length - sizeof(ms.ms_page2) - sizeof(ms.ms_page3) - sizeof(ms.ms_page4); if(ms.ms_page37.pgcode == 37) { ptr = (char *)&ms.ms_page2; bcopy((char *)&ms.ms_page37, ptr, sizeof(ms.ms_page37)); } } /* Adjust the length for the RRD40 disk */ if(rrd40_disk) { ms.ms_length = ms.ms_length - sizeof(ms.ms_page2) - sizeof(ms.ms_page3) - sizeof(ms.ms_page4); ptr = (char *)&ms.ms_page2; bcopy((char *)&ms.ms_page3, ptr, sizeof(ms.ms_page3)); } printf("\nChanging disk drive parameters for device (%s).\n", rzdisk); if(execute_rzcmd(SCSI_MODE_SELECT, (char *)&ms) != SUCCESS) { geterror(); return; } return;interactive: printf("\nCHANGING DISK DRIVE PARAMETERS INTERACTIVELY!!!\n"); printstr("\nARE YOU SURE (y/n)? "); if(!confirm()) return; bzero((char *)&ms, sizeof(ms)); ms.ms_pgcode = 0x3f; ms.ms_length = sizeof(ms) - 4; ms.ms_pgctrl = CURRENT_VALUES; if(execute_rzcmd(SCSI_MODE_SENSE, (char *)&ms) != SUCCESS) { geterror(); return; } bzero((char *)&msc, sizeof(msc)); msc.ms_pgcode = 0x3f; msc.ms_length = sizeof(ms) - 4; msc.ms_pgctrl = CHANGED_VALUES; if(execute_rzcmd(SCSI_MODE_SENSE, (char *)&msc) != SUCCESS) { geterror(); return; } printf("\nBlock descriptor:\n"); printf(" Density code\t\t\t\t%d\n", ms.ms_desc.density_code); printf(" Number of blocks\t\t\t%d\n", ((ms.ms_desc.nblks2<<16) + (ms.ms_desc.nblks1<<8) + ms.ms_desc.nblks0)); printf(" Block length\t\t\t\t%d\n", ((ms.ms_desc.blklen2<<16) + (ms.ms_desc.blklen1<<8) + ms.ms_desc.blklen0)); printstr("\nDo you want to change the block length (y/n)? "); if(confirm()) { printstr("Enter the new block length? "); value = getinteger(); ms.ms_desc.blklen2 = ((value >> 16) & 0xff); ms.ms_desc.blklen1 = ((value >> 8) & 0xff); ms.ms_desc.blklen0 = ((value >> 0) & 0xff); } ms.ms_desc.density_code &= msc.ms_desc.density_code; ms.ms_desc.nblks2 &= msc.ms_desc.nblks2; ms.ms_desc.nblks1 &= msc.ms_desc.nblks1; ms.ms_desc.nblks0 &= msc.ms_desc.nblks0; printf("\nPage 1 error recovery parameters:\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -