Omeh2018

Untitled

Oct 1st, 2020
1,282
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include <sys/io.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <ctype.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10.  
  11. #pragma pack(1)
  12.  
  13. #define ATA_SR_BSY     0x80
  14. #define ATA_SR_DRDY    0x40
  15. #define ATA_SR_DF      0x20
  16. #define ATA_SR_DSC     0x10
  17. #define ATA_SR_DRQ     0x08
  18. #define ATA_SR_CORR    0x04
  19. #define ATA_SR_IDX     0x02
  20. #define ATA_SR_ERR     0x01
  21.  
  22. // error consts
  23. #define ATA_ER_BBK      0x80
  24. #define ATA_ER_UNC      0x40
  25. #define ATA_ER_MC       0x20
  26. #define ATA_ER_IDNF     0x10
  27. #define ATA_ER_MCR      0x08
  28. #define ATA_ER_ABRT     0x04
  29. #define ATA_ER_TK0NF    0x02
  30. #define ATA_ER_AMNF     0x01
  31.  
  32. struct ide_id {
  33.         short general_conf;
  34.         short ob[9];
  35.         char sn[20];
  36.         short ob1[3];
  37.         char fwver[8];
  38.         char model[40];
  39.         short f1;
  40.         short res1;
  41.         short cap[2];
  42.         short ob2[9];
  43.         int lba28sec;
  44.         short ob3;
  45.         short mwdmamodes;
  46.         short piomodes;
  47.         short ob4[15];
  48.         short verma;
  49.         short vermi;
  50.         short features[6];
  51.         short dmamodes;
  52.         short secerasetime;
  53.         short ensecerasetime;
  54.         short apm;
  55.         short mpr;
  56.         short hwrs;
  57.         short ob5[6]; // +1
  58.         int lba48sec;
  59.         short ob6[13];
  60.         short wps;
  61.         short ob7[8];
  62.         short rms;
  63.         short secstat;
  64.         char vendorspec[62];
  65.         short cpapower;
  66.         char reserved_cf[30];
  67.         char media_sn[60];
  68.         char res[98];
  69.         short in;
  70. };
  71.  
  72.  
  73. struct zone_header {
  74.     short u1;
  75.     short zones;
  76.     char u2[0x10];
  77. } ;
  78.  
  79. struct zone_rec {
  80.     int start_cyl;
  81.     int end_cyl;
  82.     int start_sec;
  83.     char pad[2];
  84.     int end_sec;
  85.     char pad2[2];
  86. } ;
  87.  
  88. unsigned char regs;
  89. unsigned int busy, drdy, df, dsc, drq, corr, idx, err, ready, drsc;
  90. unsigned int bbk,unc,mc,idnf,mcr,abrt,tk0nf,amnf;
  91. unsigned short b0, b1,b2,b3,b4,b5,b6,b7;
  92. int p0,p1,p2,p3,p4,p5,p6,p7;
  93. int sa_spt, sa_tracks, num_of_heads, verbose;
  94.  
  95. void read_regs();
  96. void read_error();
  97. void status(int);
  98.  
  99. int waitready(int secs);
  100. int waitnobusy(int secs);
  101. int waitdrq(int secs);
  102. int waitnodrq(int secs);
  103.  
  104. int vsc_mode_on();
  105. int vsc_mode_off();
  106.  
  107. void write_buffer (char *sector);
  108. void read_buffer (char *sector);
  109.  
  110. int wd_dump_cp5 (char *buff);
  111.  
  112. int wd_rw_buffer_cmd(unsigned char length);
  113. int wd_send_full_cmd(short command, short p1, short p2, short p3, short p4, short p5, short p6);
  114. int wd_read_pchs(char *buffer, short head, int track, short sector, short scount);
  115. int wd_write_pchs(char *buffer, short head, int track, short sector, short scount);
  116. int wd_getcp(short cp, char **out_buff, int *len);
  117. int wd_send_cmd(short command, short para1 , short para2);
  118. int wd_id (struct ide_id *d);
  119. int write_file_to_reserved(char *filename);
  120. int read_file_from_reserved(char *filename);
  121. void flip (char *buf,int len);
  122. int get_sa_tracks(char *buf, int size);
  123. int get_sa_spt(char *buf);
  124.  
  125. int main(int argc, char **argv)
  126. {
  127.  
  128.     int c=0,portset=0;
  129.     int read_file=0, write_file=0,dump_zone_file=0;
  130.     int baseport=0;
  131.     char *bp=NULL;
  132.     char *filename=NULL;
  133.  
  134.     while ( (c = getopt(argc, argv, "hvzp:r:w:")) != -1 )
  135.     {
  136.  
  137.         switch (c)
  138.         {
  139.             case    'p':
  140.                 bp=optarg;
  141.                 portset=1;
  142.                 break;
  143.             case    'r':
  144.                 filename=optarg;
  145.                 read_file=1;
  146.                 break;
  147.             case    'w':
  148.                 filename=optarg;
  149.                 write_file=1;
  150.                 break;
  151.             case    'z':
  152.                 dump_zone_file=1;
  153.                 break;
  154.             case    'v':
  155.                 verbose=1;
  156.                 break;
  157.             case    'h':
  158.                 printf("usage: %s -p port [-r file] [-w filename] [-z] [-v]\n",argv[0]);
  159.                 printf("-r file     : read entire reserved area to file\n");
  160.                 printf("-w file     : write file onto reserved area\n");
  161.                 printf("-v      : verbose output\n");
  162.                 printf("-z      : dump zone file\n");
  163.                 printf("-h      : print this help\n");
  164.                 exit(1);
  165.                 break;
  166.         }
  167.        
  168.  
  169.     }
  170.  
  171.  
  172.     if (portset!=1)
  173.     {
  174.         printf("usage: %s -p port\ne.g. %s -p 0x0170\n",argv[0],argv[0]);
  175.         return(1);
  176.     }
  177.  
  178.         if (sscanf(bp, "0x%4x", &baseport))
  179.         {
  180.                 printf("using port address: 0x%04X\n\n", baseport);
  181.         } else {
  182.             if (sscanf(bp, "%4x", &baseport))
  183.                     printf("using port address: 0x%04X\n", baseport);
  184.         else
  185.         {
  186.             printf("unable to parse port argument (%s), aborting\n\n",bp);
  187.             return(1);
  188.         }
  189.         }
  190.  
  191.  
  192.  
  193.     // check for permissions
  194.     if (0!=iopl(3))
  195.     {
  196.         printf("can't change io privilege level, aborting\n");
  197.         return(1);
  198.     }
  199.  
  200.     p0=baseport;   
  201.  
  202.     p1=p0+1;
  203.     p2=p1+1;
  204.     p3=p2+1;
  205.     p4=p3+1;
  206.     p5=p4+1;
  207.     p6=p5+1;
  208.     p7=p6+1;
  209.  
  210.  
  211.     // also check if the drive model is what this POC is for...
  212.     char *poc_for_model="WDC WD2500KS-00MJB0";
  213.  
  214.     // disable interrupts?
  215.    
  216.     struct ide_id d;
  217.     wd_id(&d);
  218.  
  219.     if (verbose)
  220.         status(3);
  221.  
  222.     char model[64];
  223.     memset(model,0,64);
  224.     memcpy(model,d.model,40);
  225.     flip(model,40);
  226.     printf("Model: %s\n",model);
  227.  
  228.     char temp[64]={0};
  229.     memcpy(temp,d.sn,20);
  230.     flip(temp,20);
  231.     printf("S/N: %s\n",temp);
  232.  
  233.     memset(temp,0,64);
  234.     memcpy(temp,d.fwver,8);
  235.     flip(temp,8);
  236.     printf("F/W Ver:\t\t%s\n",temp);
  237.     printf ("LBA24:%d\tLBA48:%d\n",d.lba28sec, d.lba48sec);
  238.  
  239.     // checking for a specific 250GB hawk, but any other 250GB hawk would work just fine.
  240.     if (0!=strncmp (poc_for_model, model, strlen(poc_for_model)))
  241.     {
  242.         printf("POC works only on %s, the drive on port (%04X) is (%s), aborting\n",poc_for_model,p0,model);
  243.         exit(1);
  244.     }
  245.  
  246.  
  247.     char *out_buff;
  248.     int len;
  249.     // read configuration page 0x05 (zone list)
  250.     if (0==wd_getcp(0x05, &out_buff,&len))
  251.     {
  252.         sa_spt=get_sa_spt(out_buff);
  253.         sa_tracks=get_sa_tracks(out_buff,len*512);
  254.         num_of_heads=6; // constant for now.
  255.  
  256.         printf("\n\nService area sectors-per-track (%d)\nService area tracks (%d)\nNum of heads(%d)\nUnused reversed space (%d sectors [%d bytes])\n",sa_spt,sa_tracks,num_of_heads, sa_tracks*sa_spt*(num_of_heads - 2), sa_tracks*sa_spt*(num_of_heads - 2) * 512);
  257.     }
  258.  
  259.  
  260.     if (dump_zone_file)
  261.     {
  262.         wd_dump_cp5(out_buff);
  263.     }
  264.  
  265.     if (read_file)
  266.     {
  267.         printf("reading from SA to (%s) returned (%d)",filename,read_file_from_reserved(filename));
  268.     } else if (write_file) {
  269.         printf("writing to SA (%s) returned (%d)",filename,write_file_to_reserved(filename));
  270.     }
  271.  
  272.     return(vsc_mode_off());
  273. }
  274.  
  275. void write_buffer (char *sector)
  276. {
  277.     outsw(p0, sector, 256);
  278. }
  279.  
  280. void read_buffer (char *sector)
  281. {
  282.     insw(p0, sector, 256);
  283. }
  284.  
  285. void status(int times)
  286. {
  287.     int i=0;
  288.     printf("byte\tBSY\tDRDY\tDF\tDSC\tDRQ\tCORR\tIDX\tERR\tBBK\tUNC\tMC\tIDNF\tMCR\tABRT\tTK0NF\tAMNF\n");
  289.  
  290.     for (i=0;i<times;i++)
  291.     {
  292.         read_regs();
  293.         read_error();
  294.         printf("(%x)\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",regs,busy,drdy,df,dsc,drq,corr,idx,err,bbk,unc,mc,idnf,mcr,abrt,tk0nf,amnf);
  295.         usleep(200000);
  296.     }
  297. }
  298.  
  299. void read_regs()
  300. {
  301.  
  302.     unsigned char s ;
  303.     s = inb(p7);
  304.  
  305.     regs=s;
  306.    
  307.     busy = ATA_SR_BSY == (s & ATA_SR_BSY);
  308.     drdy = ATA_SR_DRDY == (s & ATA_SR_DRDY);        //drive ready
  309.     df = ATA_SR_DF == (s & ATA_SR_DF);
  310.     dsc = ATA_SR_DSC == (s & ATA_SR_DSC);           // drive seek complete
  311.     drq = ATA_SR_DRQ == (s & ATA_SR_DRQ);
  312.     corr = ATA_SR_CORR == (s & ATA_SR_CORR);
  313.     idx = ATA_SR_IDX == (s & ATA_SR_IDX);
  314.     err = ATA_SR_ERR == (s & ATA_SR_ERR);
  315.  
  316.     ready = drsc = drdy & dsc;
  317.    
  318. }  
  319.  
  320. void read_error()
  321. {
  322.     unsigned char e;
  323.     e = inb(p1);
  324.     bbk = ATA_ER_BBK == (e & ATA_ER_BBK);
  325.     unc = ATA_ER_UNC == (e & ATA_ER_UNC);
  326.     mc = ATA_ER_MC == (e & ATA_ER_MC);
  327.     idnf = ATA_ER_IDNF == (e & ATA_ER_IDNF);
  328.     mcr = ATA_ER_MCR == (e & ATA_ER_MCR);
  329.     abrt = ATA_ER_ABRT == (e & ATA_ER_ABRT);
  330.     tk0nf = ATA_ER_TK0NF == (e & ATA_ER_TK0NF);
  331.     amnf = ATA_ER_AMNF == (e & ATA_ER_AMNF);
  332.  
  333. }  
  334.  
  335. int wd_id (struct ide_id *d)
  336. {
  337.     if (verbose)
  338.         printf ("wd_id()\n");
  339.  
  340.     // send 0xa0 to p6  --select master
  341.     outb(0xa0, p6);
  342.  
  343.     // send 0xec to p7  --send identify cmd
  344.     outb(0xec, p7);
  345.  
  346.     if (waitdrq(10))
  347.     {
  348.         printf("not ready to read, aborting\n");
  349.     }
  350.  
  351.     // read buffer
  352.     char buff[512];
  353.     read_buffer (buff);
  354.  
  355.     memcpy(d,buff,sizeof(struct ide_id));
  356.  
  357.     return(0); 
  358. }
  359.  
  360. int wd_read_pchs ( char *buffer, short head, int track, short sector, short scount)
  361. {
  362.  
  363.     int sectorsread;
  364.     long int sectorslow;
  365.     long int sectorshigh;
  366.     char a[512];
  367.     int len;
  368.     int rc;
  369.  
  370.     // send 0xa0 to p6  --select master
  371.     outb(0xa0, p6);
  372.  
  373.     if (verbose)
  374.         printf("wd_read_pchs(head=%d)(track=%d)(sector=%d)(scount=%d)\n",head,track,sector,scount);
  375.  
  376.     if (waitready(3))
  377.     {
  378.         printf("wd_read_pchs: drive not ready, aborting\n");
  379.         status(3);
  380.         return(1);
  381.     }
  382.    
  383.     if (vsc_mode_on())
  384.     {  
  385.         printf("failed to get into vsc mode, aborting\n");
  386.         return (1);
  387.     }
  388.  
  389.     rc=wd_send_full_cmd(0x000c, 0x0001, (track & 0xffff), (track >> 16) & 0xffff , head, sector, scount);
  390.     if (rc)
  391.     {
  392.         printf("wd_read_pchs: wd_send_full_cmd failed, aborting\n");
  393.         return(1);
  394.     }
  395.  
  396.     if (waitnodrq(3)) {
  397.         printf("DRQ=1, ERROR\n");
  398.         return(1);
  399.     } else {
  400.         if (verbose)
  401.         {
  402.             printf("DRQ=0, OK\n");
  403.             status(4);
  404.         }
  405.     }
  406.  
  407.     sectorslow = inb(p4);
  408.     sectorshigh = inb(p5);
  409.     len = sectorslow+(sectorshigh<<8);
  410.  
  411.     if (len<1)
  412.     {
  413.         printf("len<1, aborting\n");
  414.         return(1);
  415.     }
  416.  
  417.     sectorsread=0;
  418.  
  419.     while (len>sectorsread)
  420.     {
  421.         rc=wd_rw_buffer_cmd(1);
  422.        if (rc)
  423.         {
  424.             printf("wd_rw_buffer_cmd, failed\n");
  425.             return(1);
  426.         }
  427.  
  428.         read_regs();
  429.         while (drq)
  430.         {
  431.             memset(a,0,512);
  432.             read_buffer(a);
  433.  
  434.             memcpy(buffer+(sectorsread*512), a, 512);
  435.  
  436.             sectorsread++;
  437.  
  438.             rc=waitready(60);
  439.             if (rc) return(1);
  440.  
  441.             read_regs();
  442.             if(err)
  443.             {
  444.                 printf("Error:\n");
  445.                 status(1);
  446.                 return(1); 
  447.             }
  448.         }
  449.     }
  450.  
  451.     if (sectorsread!=len)
  452.     {
  453.         printf("didn't complete read operation\n");
  454.         return(1);
  455.     }
  456.  
  457.     return(0);
  458. }
  459.  
  460. int vsc_mode_on()
  461. {
  462.  
  463.     int rc;
  464.  
  465.     // send 0xa0 to p6  --select master
  466.     outb(0xa0, p6);
  467.  
  468.     if (verbose)
  469.         printf("vsc_mode_on_start:\n");
  470.  
  471.     rc = waitnobusy(3);
  472.     if (rc)
  473.     {
  474.         printf("vsc_mode_on: busy, exiting\n");
  475.         status(3);
  476.         return(1);
  477.     }
  478.  
  479.     outb(0x45,p1);
  480.     outb(0x00,p2);
  481.     outb(0x00,p3);
  482.     outb(0x44,p4);
  483.     outb(0x57,p5);
  484.     outb(0xA0,p6);
  485.     outb(0x80,p7);
  486.  
  487.     rc=waitnobusy(10);
  488.     if (rc)
  489.     {
  490.         printf("wait-no-busy, timed out, aborting\n");
  491.         return(1);
  492.     }
  493.  
  494.     if(waitnodrq(3))
  495.     {
  496.         printf("drq still 1, aborting\n");
  497.         status(3);
  498.         return(1);
  499.     }
  500.    
  501.     if (verbose)
  502.         printf ("vsc_mode_on: OK\n");
  503.  
  504.     return(0);
  505.    
  506. }
  507.  
  508. int vsc_mode_off()
  509. {
  510.  
  511.     int rc;
  512.  
  513.     // send 0xa0 to p6  --select master
  514.     outb(0xa0, p6);
  515.  
  516.     if (verbose)
  517.         printf("vsc_mode_on_start:\n");
  518.  
  519.     rc = waitnobusy(3);
  520.     if (rc)
  521.     {
  522.         printf("vsc_mode_on: busy, exiting\n");
  523.         status(3);
  524.         return(1);
  525.     }
  526.  
  527.     outb(0x44,p1);
  528.     outb(0x00,p2);
  529.     outb(0x00,p3);
  530.     outb(0x44,p4);
  531.     outb(0x57,p5);
  532.     outb(0xA0,p6);
  533.     outb(0x80,p7);
  534.  
  535.     rc=waitnobusy(10);
  536.     if (rc)
  537.     {
  538.         printf("wait-no-busy, timed out, aborting\n");
  539.         return(1);
  540.     }
  541.  
  542.     read_regs();
  543.     if(drq)
  544.     {
  545.         printf("drq still 1, aborting\n");
  546.         status(3);
  547.         return(1);
  548.     }
  549.     return(0);
  550. }
  551.  
  552. int wd_rw_buffer_cmd(unsigned char length) 
  553. {
  554.  
  555.     int rc;
  556.  
  557.     // send 0xa0 to p6  --select master
  558.     outb(0xa0, p6);
  559.  
  560.     rc=waitnobusy(3);
  561.     if (rc)
  562.     {  
  563.         printf ("drive busy, aborting\n");
  564.         status(3);
  565.         return 1;
  566.     }
  567.  
  568.     outb(0xD5,p1);
  569.     outb(length,p2);
  570.     outb(0xbf,p3);
  571.     outb(0x4f,p4);
  572.     outb(0xc2,p5);
  573.     outb(0xa0,p6);
  574.     outb(0xb0,p7);
  575.  
  576.     rc=waitnobusy(60);
  577.     if (rc) {
  578.         printf ("io-wait-on-busy timeout,aborting\n");
  579.         status(2);
  580.         return(1);
  581.     }
  582.  
  583.     if (0!=waitdrq(3)) {
  584.         printf ("drq not on, aborting\n");
  585.         status(2);
  586.         return(1);
  587.     }
  588.  
  589.     if (verbose)
  590.         printf("wd_rw_buffer_cmd: OK\n");
  591.  
  592.     return(0);
  593. }
  594.  
  595.  
  596. int wd_send_full_cmd(short command, short par1, short par2, short par3, short par4, short par5, short par6)
  597. {
  598.     char a[512];
  599.     int rc;
  600.  
  601.     memset(a,0, 512);
  602.  
  603.     a[1]=(command>>8) & 0xff ;
  604.     a[0]=(command & 0x00ff);
  605.  
  606.     a[3]=(par1>>8) & 0xff;
  607.     a[2]=(par1 & 0x00ff);
  608.  
  609.     a[5]=(par2>>8) & 0xff;
  610.     a[4]=(par2 & 0x00ff);
  611.  
  612.     a[7]=(par3>>8) & 0xff;
  613.     a[6]=(par3 & 0x00ff);
  614.  
  615.     a[9]=(par4>>8) & 0xff;
  616.     a[8]=(par4 & 0x00ff);
  617.  
  618.     a[11]=(par5>>8) & 0xff;
  619.     a[10]=(par5 & 0x00ff);
  620.  
  621.     a[13]=(par6>>8) & 0xff;
  622.     a[12]=(par6 & 0x00ff);
  623.  
  624.  
  625.     outb(0xa0,p6);
  626.     read_regs();
  627.  
  628.     if (busy)
  629.     {
  630.         printf("wd_send_full_cmd: busy, exiting\n");
  631.         return 1;
  632.     }
  633.  
  634.     outb(0xd6,p1); 
  635.     outb(0x01,p2);
  636.     outb(0xbe,p3);
  637.     outb(0x4f,p4);
  638.     outb(0xc2,p5);
  639.     outb(0xa0,p6);
  640.     outb(0xb0,p7);
  641.  
  642.     rc=waitnobusy(60);
  643.     if(rc)
  644.     {
  645.  
  646.         printf("wd_send_full_cmd: waitnobusy (1), exiting\n");
  647.         return(1);
  648.     }
  649.  
  650.     read_regs();
  651.     if(!drq) {
  652.         printf ("wd_send_full_cmd: drq(%d), exiting\n",drq);
  653.         return(1);
  654.     }
  655.  
  656.     write_buffer(a);
  657.  
  658.     rc=waitnobusy(5);
  659.     if (rc) {
  660.         printf("wd_send_full_cmd: waitnobusy=%d, exiting\n,",rc);
  661.         return(1);
  662.     }
  663.  
  664.     read_regs();
  665.     if (err)
  666.     {
  667.            
  668.         printf("wd_send_full_cmd: error register is on..\n");
  669.         status(2);
  670.        
  671.         return(1);
  672.     }
  673.  
  674.     return(0);
  675. }
  676.  
  677. int waitdrq(int secs)
  678. {
  679.  
  680.     int wait_time=500;
  681.     int retries=secs*1000000/(wait_time);
  682.  
  683.     read_regs();
  684.     while ((!drq) && (retries>=0))
  685.     {
  686.         usleep (wait_time);
  687.         retries--;
  688.         read_regs();
  689.     }  
  690.  
  691.     if (retries>0)
  692.         return (0);
  693.     else
  694.         return(1);
  695.    
  696. }
  697.  
  698. int waitnodrq(int secs)
  699. {
  700.  
  701.     int wait_time=500;
  702.     int retries=secs*1000000/(wait_time);
  703.  
  704.     read_regs();
  705.     while ((drq) && (retries>=0))
  706.     {
  707.         usleep (wait_time);
  708.         retries--;
  709.         read_regs();
  710.     }  
  711.  
  712.     if (retries>0)
  713.         return (0);
  714.     else
  715.         return(1);
  716.    
  717. }
  718.  
  719. int waitready(int secs)
  720. {
  721.    
  722.     int wait_time=500;
  723.     int retries=secs*1000000/(wait_time);
  724.  
  725.     read_regs();
  726.     while ( (!ready) && (retries>=0))
  727.     {
  728.         usleep (wait_time);
  729.         retries--;
  730.         read_regs();
  731.     }  
  732.    
  733.     if (retries>0)
  734.         return (0);
  735.     else
  736.         return(1);
  737.    
  738. }
  739.  
  740. int waitnobusy(int secs)
  741. {
  742.  
  743.     int wait_time=500;
  744.     int retries=secs*1000000/(wait_time);
  745.  
  746.     read_regs();
  747.     while ((busy) && (retries>=0))
  748.     {
  749.         usleep (wait_time);
  750.         retries--;
  751.         read_regs();
  752.     }  
  753.    
  754.     if ((retries==0) && busy)
  755.         return (1);
  756.     else
  757.         return(0);
  758.    
  759. }
  760.  
  761.  
  762. int wd_send_cmd(short command, short par1 , short par2)
  763. {
  764.  
  765.     char a[512];
  766.     int rc;
  767.  
  768.     if (verbose)
  769.         printf("debug: (command=%04X)(p1=%04X)(p2=%04X)\n",command,par1,par2);
  770.  
  771.     memset(a,0, 512);
  772.  
  773.     a[1]=(command>>8) & 0xff ;
  774.     a[0]=(command & 0x00ff);
  775.  
  776.     a[3]=(par1>>8) & 0xff;
  777.     a[2]=(par1 & 0x00ff);
  778.  
  779.     a[5]=(par2>>8) & 0xff;
  780.     a[4]=(par2 & 0x00ff);
  781.  
  782.     // select master
  783.     outb(0xa0,p6);
  784.  
  785.     rc = waitnobusy(3);
  786.     if (rc)
  787.     {
  788.         printf("wd_send_full_cmd: drive busy, exiting\n");
  789.         return 1;
  790.     }
  791.  
  792.     outb(0xd6,p1);
  793.     outb(0x01,p2);
  794.     outb(0xbe,p3);
  795.     outb(0x4f,p4);
  796.     outb(0xc2,p5);
  797.     outb(0xa0,p6);
  798.     outb(0xb0,p7);
  799.  
  800.     rc=waitnobusy(3);
  801.     if(rc)
  802.     {
  803.  
  804.         printf("wd_send_full_cmd: waitnobusy (1), exiting\n");
  805.         return(1);
  806.     }
  807.  
  808.     read_regs();
  809.     if(!drq) {
  810.         printf ("wd_send_full_cmd: drq(%d), exiting\n",drq);
  811.         return(1);
  812.     }
  813.  
  814.     write_buffer(a);
  815.  
  816.     rc=waitnobusy(10);
  817.     if (rc) {
  818.         printf("wd_send_full_cmd: waitnobusy=%d, exiting\n,",rc);
  819.         return(1);
  820.     }
  821.  
  822.     read_regs();
  823.     if (err)
  824.     {
  825.            
  826.         printf("wd_send_full_cmd: error register is on..\n");
  827.         status(2);
  828.        
  829.         return(1);
  830.     }
  831.  
  832.     return(0);
  833. }
  834.  
  835.  
  836. int wd_getcp(short cp, char **out_buff, int *len)
  837. {
  838.  
  839.     char buff[512];
  840.     char *new_buff;
  841.     unsigned char i;
  842.     int rc = 0;
  843.  
  844.     // choose primary port
  845.     outb(0xa0,p6);
  846.  
  847.     read_regs();
  848.     if (busy)
  849.     {
  850.         printf("wd_getcp: drive busy, leaving");
  851.         return(1); 
  852.     }
  853.    
  854.     if (vsc_mode_on())
  855.     {
  856.         printf("wd_getcp: vsc_mode_on failed, aborting\n");
  857.         return(1);
  858.     }
  859.  
  860.     rc = wd_send_cmd(0x000d, cp, 0x0000);
  861.     if (rc)
  862.     {
  863.         printf("wd_getcp: wd_send_cmd failed, aborting\n");
  864.         status(2);
  865.         return(1);
  866.     }
  867.  
  868.     read_regs();
  869.     if (drq)
  870.     {
  871.         printf("wd_getcp: drq on, error, aborting\n");
  872.         status(2);
  873.         return(1);
  874.     }  
  875.  
  876.  
  877.     // read len
  878.     (*len) = inb(p4);
  879.  
  880.     new_buff=malloc((*len)*512);
  881.  
  882.     if (verbose)
  883.         printf("wd_getcp: CP (%x) len is (%x)\n", cp, *len);
  884.  
  885.     rc = wd_rw_buffer_cmd((*len));
  886.     if (rc)
  887.     {
  888.         printf("wd_getcp: wd_rw_buffer_cmd failed, aborting\n");
  889.         return(1);
  890.     }
  891.  
  892.     for (i=0;i<(*len);i++)
  893.     {
  894.         if (verbose)
  895.             printf("reading part (%d) of (%d)\n", i,(*len));
  896.  
  897.         if (0==waitdrq(3))
  898.         {
  899.             read_buffer(buff);
  900.             memcpy(new_buff+(i*512), buff,512);
  901.             waitnobusy(3);
  902.         }
  903.     }
  904.  
  905. #ifdef DEBUG
  906.     FILE *f;
  907.     char fn[64];
  908.     sprintf(fn, "cp_%x.bin",cp);
  909.     f = fopen(fn, "w");
  910.     if (f) {
  911.         fwrite(new_buff, 512*(*len),1, f);
  912.        fclose(f);
  913.     } else {
  914.         printf ("can't open file for writing... exiting\n");
  915.         return(1);
  916.     }
  917. #endif
  918.     (*out_buff)=new_buff;
  919.     return(0);
  920. }
  921.  
  922. int get_sa_spt(char *buff)
  923. {
  924.  
  925.     int pos=0;
  926.     short spt;
  927.  
  928.     pos+=sizeof(struct zone_header);
  929.     pos+=sizeof(struct zone_rec);
  930.  
  931.     memcpy(&spt,buff+pos, 2);
  932.  
  933.     return(spt);
  934. }
  935.  
  936.  
  937. int get_sa_tracks(char *buff, int size)
  938. {
  939.     struct zone_rec rec1;
  940.  
  941.     if ( (sizeof(struct zone_header) + sizeof(struct zone_rec)) < size )
  942.     {
  943.         memcpy(&rec1, buff + sizeof(struct zone_header), sizeof(struct zone_rec));
  944.         return(abs(rec1.start_cyl));
  945.     } else {
  946.         return(0);
  947.     }
  948. }
  949.  
  950.  
  951.  
  952. int wd_dump_cp5 (char *buff)
  953. {
  954.  
  955.     int i=0;
  956.     int h=0;
  957.     int num_of_heads=6;
  958.  
  959.     struct zone_rec rec1;
  960.     struct zone_header z1;
  961.  
  962.     memcpy(&z1, buff, sizeof(struct zone_header));
  963.  
  964.     int pos=0;
  965.     short spt;
  966.     pos+=sizeof(struct zone_header);   
  967.     for (i=0;i<z1.zones;i++)   
  968.     {
  969.         memcpy(&rec1, buff+pos, sizeof(struct zone_rec));
  970.         printf("cyl(%d,%d) sector(%d,%d)",rec1.start_cyl,rec1.end_cyl,rec1.start_sec,rec1.end_sec);
  971.  
  972.  
  973.         pos+=sizeof(struct zone_rec);
  974.  
  975.         for(h=0;h<num_of_heads;h++)
  976.         {
  977.             memcpy(&spt,buff+pos, 2);
  978.             pos+=2;
  979.             printf (" (h=%d)(spt=%d)",h,spt);
  980.         }
  981.         printf("\n");
  982.     }
  983.  
  984.     return(0);
  985. }
  986.  
  987. int wd_write_pchs ( char *buffer, short head, int track, short sector, short scount)
  988. {
  989.     int sectorswritten;
  990.     long int sectorslow;
  991.     long int sectorshigh;
  992.     char a[512];
  993.     int len;
  994.     int rc;
  995.  
  996.     if (verbose)
  997.         printf("wd_write_pchs(head=%d)(track=%d)(sector=%d)(scount=%d)\n",head,track,sector,scount);
  998.  
  999.     outb(0xa0, p6);
  1000.  
  1001.     if (waitready(3))
  1002.     {
  1003.         printf("wd_write_pchs, drive not ready, aborting\n");
  1004.         status(3);
  1005.         return(1);
  1006.     }
  1007.    
  1008.     if (vsc_mode_on())
  1009.     {  
  1010.         printf("failed to get into vsc mode, aborting\n");
  1011.         return (1);
  1012.     } else {
  1013.         if (verbose)
  1014.             printf("vsc_mode_on: OK\n");
  1015.     }
  1016.  
  1017.  
  1018.     if (verbose)
  1019.         printf("debug: track(%04X)(%02X)(%02X)\n",track, (track & 0xffff), (track >> 16) & 0xffff);
  1020.  
  1021.     rc=wd_send_full_cmd(0x000c, 0x0002, (track & 0xffff), (track >> 16) & 0xffff , head, sector, scount);
  1022.     if (rc!=0)
  1023.     {
  1024.         printf("wd_send_full_cmd failed, aborting\n");
  1025.         return(1);
  1026.     } else {
  1027.         if (verbose)
  1028.             printf("wd_send_full_cmd: OK\n");
  1029.     }
  1030.  
  1031.     read_regs();
  1032.     if (drq) {
  1033.         printf("DRQ=1, ERROR\n");
  1034.         return(1);
  1035.     } else {
  1036.         if (verbose)
  1037.         {
  1038.             printf("DRQ=0, OK\n");
  1039.             status(2);
  1040.         }
  1041.     }
  1042.  
  1043.     sectorslow = inb(p4);
  1044.     sectorshigh = inb(p5);
  1045.     len = sectorslow+(sectorshigh<<8);
  1046.  
  1047.     if (len<1) return(1);
  1048.  
  1049.     sectorswritten=0;
  1050.  
  1051.     while (len>sectorswritten)
  1052.     {
  1053.             if (wd_rw_buffer_cmd(1))
  1054.         {
  1055.             printf("wd_rw_buffer_cmd, failed\n");
  1056.             return(1);
  1057.         }
  1058.  
  1059.         read_regs();
  1060.         while (drq)
  1061.         {
  1062.             if (memcpy(a,buffer+(sectorswritten*512),512))
  1063.             {
  1064.                 write_buffer(a);
  1065.             } else {
  1066.                 printf("error reading input buffer\n");
  1067.                 return(1);
  1068.             }
  1069.             sectorswritten++;
  1070.  
  1071.             rc=waitready(10);
  1072.             if (rc < 0)
  1073.             {  
  1074.                 printf("not ready aborting\n");
  1075.                 return(1);
  1076.             }
  1077.             read_regs();
  1078.             if(err)
  1079.             {
  1080.                 printf("write completed with errors, aborting\n");
  1081.                 return(1);
  1082.             }
  1083.         }
  1084.     }
  1085.  
  1086.     if (sectorswritten!=len)
  1087.     {  
  1088.         printf("didn't complete writing\n");
  1089.         return(1);
  1090.     }
  1091.  
  1092.     return(0);
  1093. }
  1094.  
  1095. void flip (char *buf,int len)
  1096. {
  1097.     int i=0;
  1098.     for (i=0;i<len-1;i+=2)
  1099.     {
  1100.         char k;
  1101.         k=buf[i];
  1102.         buf[i]=buf[i+1];
  1103.         buf[i+1]=k;
  1104.     }
  1105. }
  1106.  
  1107. int read_file_from_reserved(char *filename)
  1108. {
  1109.     // read from reserved areas 2,3,4,5
  1110.  
  1111.     char *whole_track;
  1112.     int h=0;
  1113.  
  1114.     if (sa_spt<=0)
  1115.     {
  1116.         printf("can't read sa_spt, aborting");
  1117.         return(1);
  1118.     }
  1119.  
  1120.     whole_track = malloc(sa_spt*512);
  1121.  
  1122.     FILE *f;
  1123.     f = fopen(filename, "w");
  1124.  
  1125.     h=2;    // first head with unused "service-area" space.
  1126.        
  1127.     int head,track;
  1128.     for (head=h;head<num_of_heads;head++)
  1129.     {
  1130.         for (track=-1;track>=(-1*sa_tracks);track--)
  1131.         {  
  1132.             printf("reading head(%d) track(%d)\n",head,track);
  1133.             if (0==wd_read_pchs(whole_track,head,track,1,sa_spt))
  1134.             {
  1135.                 fwrite(whole_track, sa_spt*512, 1, f);
  1136.             } else {
  1137.                 printf("wd_read_pchs failed, aborting\n");
  1138.                 return(1);
  1139.             }
  1140.         }
  1141.     }
  1142.  
  1143.     fclose(f);
  1144.     return(0);
  1145. }
  1146.  
  1147. int write_file_to_reserved(char *filename)
  1148. {
  1149.     // write to reserved areas 2,3,4,5
  1150.  
  1151.     char *whole_track;
  1152.     int size,rc=0;
  1153.  
  1154.     struct stat st;
  1155.     stat(filename, &st);
  1156.     size = st.st_size;
  1157.  
  1158.     if (sa_spt<=0)
  1159.     {
  1160.         printf("can't read sa_spt, aborting");
  1161.         return(1);
  1162.     }
  1163.  
  1164.     whole_track = malloc(sa_spt*512);
  1165.  
  1166.     if (size > (sa_spt * (sa_tracks) * 4 * 512))    // 4 is a fixed set of available heads for this drive.
  1167.     {
  1168.         printf("can't fit %s in SA, aborting (%d > %d)\n", filename, size, (sa_spt*(sa_tracks-1)*4*512));
  1169.         return(1);
  1170.     }
  1171.  
  1172.     FILE *f;
  1173.     f = fopen(filename, "r");
  1174.  
  1175.     int head=2;
  1176.     int track=-1;
  1177.     while ( (rc = fread(whole_track, 1, sa_spt*512, f)) )
  1178.     {
  1179.         // trim if not a complete sector.
  1180.         printf("writing head(%d) track(%d)\n",head,track);
  1181.         if (0==wd_write_pchs(whole_track, head, track, 1, (int)rc/512))
  1182.         {
  1183.             track--;
  1184.             if (track==-65)
  1185.             {
  1186.                 head++;
  1187.                 track=-1;
  1188.             }
  1189.         } else {
  1190.             printf("wd_write_pchs failed, aborting\n");
  1191.         }
  1192.     }
  1193.  
  1194.     printf("leaving write to file rc=%d\n",rc);
  1195.     return 0;
  1196. }
RAW Paste Data