int ata_wr_cur(struct defect_list *list) { int status; int sec_count; int x; struct badsec_lst *blc_p; struct badsec_lst *blc_p_nxt; struct defect_entry *dlist; if (list->header.magicno != (uint_t)DEFECT_MAGIC) return (-1); sec_count = list->header.count; dlist = list->list; (void) get_alts_slice(); for (x = 0; x < sec_count; x++) { /* test for unsupported list format */ if ((dlist->bfi != UNKNOWN) || (dlist->nbits != UNKNOWN)) { (void) fprintf(stderr, "BFI unsuported format for bad sectors\n"); return (-1); } if (!gbadsl_chain) { blc_p = (struct badsec_lst *)calloc(1, BADSLSZ); if (!blc_p) { (void) fprintf(stderr, "Unable to allocate memory for additional bad sectors\n"); return (-1); } gbadsl_chain = blc_p; } for (blc_p = gbadsl_chain; blc_p->bl_nxt; ) blc_p = blc_p->bl_nxt; if (blc_p->bl_cnt == MAXBLENT) { blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ); if (!blc_p->bl_nxt) { (void) fprintf(stderr, "Unable to allocate memory for additional bad sectors\n"); return (-1); } blc_p = blc_p->bl_nxt; } blc_p->bl_sec[blc_p->bl_cnt++] = (uint_t)chs2bn(dlist->cyl, dlist->head, dlist->sect); gbadsl_chain_cnt++; dlist++; } (void) updatebadsec(dpart, 0); status = put_alts_slice(); /* clear out the bad sector list chains that were generated */ if (badsl_chain) { if (badsl_chain->bl_nxt == NULL) { free(badsl_chain); } else { for (blc_p = badsl_chain; blc_p; ) { blc_p_nxt = blc_p->bl_nxt; free(blc_p); blc_p = blc_p_nxt; } } badsl_chain = NULL; badsl_chain_cnt = 0; } if (gbadsl_chain) { if (gbadsl_chain->bl_nxt == NULL) { free(gbadsl_chain); } else { for (blc_p = gbadsl_chain; blc_p; ) { blc_p_nxt = blc_p->bl_nxt; free(blc_p); blc_p = blc_p_nxt; } } gbadsl_chain = NULL; gbadsl_chain_cnt = 0; } return (status); }
int main(int argc, char *argv[]) { extern int optind; extern char *optarg; static char options[] = "Ipa:f:"; char numbuf[100]; char *nxtarg; char *alts_name; minor_t minor_val; struct stat statbuf; struct partition *part = NULL; int alts_slice = -1; int l; int p; int init_flag = 0; int print_flag = 0; int c; int i; FILE *badsecfd = NULL; struct badsec_lst *blc_p; progname = argv[0]; while ( (c=getopt(argc, argv, options)) != EOF ) { switch (c) { case 'I': init_flag = 1; break; case 'p': print_flag = 1; break; case 'a': nxtarg = optarg; for (;*nxtarg != '\0';) add_gbad(strtol(nxtarg, &nxtarg, 0)); break; case 'f': if ((badsecfd = fopen(optarg, "r")) == NULL) { fprintf(stderr, "%s: unable to open %s file\n", progname, optarg); exit(1); } break; default: giveusage(); exit(2); } } /* get the last argument -- device stanza */ if (argc != optind+1) { fprintf(stderr, "Missing disk device name\n"); giveusage(); exit(3); } devname = argv[optind]; if (stat(devname, &statbuf)) { fprintf(stderr, "%s: invalid device %s, stat failed\n", progname, devname); giveusage(); exit(4); } if ((statbuf.st_mode & S_IFMT) != S_IFCHR) { fprintf(stderr, "%s: device %s is not character special\n", progname, devname); giveusage(); exit(5); } minor_val = minor(statbuf.st_rdev); /* * NEED A DEFINE FOR THE PHYSICAL BIT (0x10) */ if ((minor_val & 0x10) == 0) { fprintf(stderr, "%s: device %s is not a physical slice\n", progname, devname); giveusage(); exit(6); } if ((minor_val % V_NUMPAR) != 0) { fprintf(stderr, "%s: device %s is not a slice 0 device\n", progname, devname); giveusage(); exit(7); } if ((devfd=open(devname, O_RDWR)) == -1) { fprintf(stderr, "%s: open of %s failed\n", progname ,devname); perror(""); exit(8); } if ((ioctl (devfd, DKIOCGGEOM, &dkg)) == -1) { fprintf(stderr, "%s: unable to get disk geometry.\n", progname); perror(""); exit(9); } if (ioctl(devfd, DKIOCGVTOC, &vtoc) == -1) { fprintf(stderr, "%s: could not get VTOC.\n", progname); giveusage(); exit(14); } if ((vtoc.v_sanity != VTOC_SANE) || (vtoc.v_version != V_VERSION)) { fprintf(stderr, "%s: invalid VTOC found.\n", progname); giveusage(); exit(15); } if (badsecfd) rd_gbad(badsecfd); #ifdef ADDBAD_DEBUG printf("\n main: Total bad sectors found= %d\n", gbadsl_chain_cnt); for (blc_p=gbadsl_chain; blc_p; blc_p=blc_p->bl_nxt) { for (i=0; i<blc_p->bl_cnt; i++) printf(" badsec=%d ", blc_p->bl_sec[i]); } printf("\n"); #endif #ifdef PPP /* * If init_flag is set, run to completion. */ if (gbadsl_chain_cnt == 0 && init_flag == 0) /* * No defects and not initializing */ exit (0); #endif if (gbadsl_chain_cnt != 0) { if (try_hw_remap () == SUCCESS) exit (0); } /* * get ALTS slice */ for (i = 0; i < V_NUMPAR && alts_slice == -1; i++) { if (vtoc.v_part[i].p_tag == V_ALTSCTR) { alts_slice = i; part = &vtoc.v_part[i]; } } if (alts_slice == -1) { fprintf(stderr, "%s: No alternates slice.\n", progname); exit(16); } l = strlen (devname); sprintf (numbuf, "%d", alts_slice); p = strlen (numbuf); alts_name = (char *)malloc (l + p); strcpy (alts_name, devname); alts_name[l - 2] = 's'; strcpy (&alts_name[l - 1], numbuf); alts_name[l + p - 1] = '\0'; if ((alts_fd=open(alts_name, O_RDWR)) == -1) { fprintf(stderr, "%s: open of %s failed\n", progname ,alts_name); perror(""); exit(9); } if (print_flag) { print_altsec (part); exit (0); } updatebadsec(part, init_flag); wr_altsctr(); if (ioctl(devfd, DKIOCADDBAD, NULL) == -1) { fprintf(stderr, "Warning: DKIOCADDBAD io control failed. System must be re-booted\n"); fprintf(stderr, "for alternate sectors to be usable.\n"); exit(17); } sync(); fclose(badsecfd); close (alts_fd); close (devfd); return(0); }
int ata_repair(diskaddr_t bn, int flag) { int status; struct badsec_lst *blc_p; struct badsec_lst *blc_p_nxt; #ifdef lint flag++; #endif (void) get_alts_slice(); if (!gbadsl_chain) { blc_p = (struct badsec_lst *)calloc(1, BADSLSZ); if (!blc_p) { (void) fprintf(stderr, "Unable to allocate memory for additional bad sectors\n"); return (-1); } gbadsl_chain = blc_p; } for (blc_p = gbadsl_chain; blc_p->bl_nxt; ) blc_p = blc_p->bl_nxt; if (blc_p->bl_cnt == MAXBLENT) { blc_p->bl_nxt = (struct badsec_lst *)calloc(1, BADSLSZ); if (!blc_p->bl_nxt) { (void) fprintf(stderr, "Unable to allocate memory for additional bad sectors\n"); return (-1); } blc_p = blc_p->bl_nxt; } blc_p->bl_sec[blc_p->bl_cnt++] = (uint_t)bn; gbadsl_chain_cnt++; (void) updatebadsec(dpart, 0); status = put_alts_slice(); /* clear out the bad sector list chains that were generated */ if (badsl_chain) { if (badsl_chain->bl_nxt == NULL) { free(badsl_chain); } else { for (blc_p = badsl_chain; blc_p; ) { blc_p_nxt = blc_p->bl_nxt; free(blc_p); blc_p = blc_p_nxt; } } badsl_chain = NULL; badsl_chain_cnt = 0; } if (gbadsl_chain) { if (gbadsl_chain->bl_nxt == NULL) { free(gbadsl_chain); } else { for (blc_p = gbadsl_chain; blc_p; ) { blc_p_nxt = blc_p->bl_nxt; free(blc_p); blc_p = blc_p_nxt; } } gbadsl_chain = NULL; gbadsl_chain_cnt = 0; } return (status); }