|
|
1.1 root 1: #include <stdio.h>
2: #include "../scsi.h"
3: #include "../scsish.h"
4: #include "../tcl.h"
5: #include "fns.h"
6:
7: #define PROGRESS \
8: if(sbase/TALK != goo){\
9: goo = sbase/TALK;\
10: time(&t2);\
11: printf("\tdoing block %ld at %s", goo*TALK, ctime(&t2));\
12: }
13:
14: static char good[256]; /* by default, all BAD */
15: typedef enum { BAD = 0, GOOD } Searchtype;
16: static int copy1(int, int, int, int, int, int, int, char *);
17: static int search(int, int, int, int, Searchtype, char *);
18:
19: int
20: sony_copy(ClientData cd, Tcl_Interp *it, int argc, char **argv)
21: {
22: int n;
23: int sdr, sbase, nblocks, ddr, dbase;
24: int starget = s_id;
25: int dtarget = s_id;
26: int wr, unwr;
27: long nb = nblocks;
28: long t1, t2;
29: long goo;
30: int lower;
31: struct scsi_return ret;
32: #define TALK 10000
33: extern char *ctime();
34:
35: if(argc != 6)
36: USAGE_RETURN
37: sdr = atoi(argv[1]);
38: sbase = atoi(argv[2]);
39: nblocks = atoi(argv[3]);
40: ddr = atoi(argv[4]);
41: dbase = atoi(argv[5]);
42: printf("copying drive (%d,%d)[%d-%d] to drive (%d,%d)[%d-%d]\n",
43: starget, sdr, sbase, sbase+nblocks-1,
44: dtarget, ddr, dbase, dbase+nblocks-1);
45: if(sony_istatus(&ret, cd->err))
46: ERR_RETURN
47: if((ret.data[100]&0x80) && (sdr == (ret.data[100]&7)))
48: lower = 0;
49: else if((ret.data[101]&0x80) && (sdr == (ret.data[101]&7)))
50: lower = 1;
51: else {
52: sprintf(cd->err, "drive %d not occupied\n", sdr);
53: ERR_RETURN
54: }
55: good[0] = good[0x81] = good[0x82] = good[0x83] = GOOD;
56: time(&t1);
57: goo = -1;
58: while(nblocks > 0){
59: /* search for a block to copy */
60: while(n = min(256, nblocks)){
61: wr = search(sdr, lower, sbase, n, GOOD, cd->err);
62: if(wr < 0)
63: break;
64: sbase += wr;
65: dbase += wr;
66: nblocks -= wr;
67: if(wr < n)
68: break;
69: PROGRESS
70: }
71: /* now copy until the first bad block */
72: while(n = min(256, nblocks)){
73: unwr = search(sdr, lower, sbase, n, BAD, cd->err);
74: if(unwr < 0)
75: break;
76: /*printf("writing %d-%d\n", sbase, sbase+unwr-1);/**/
77: if(copy1(starget, sdr, sbase, unwr, dtarget, ddr, dbase, cd->err))
78: break;
79: sbase += unwr;
80: dbase += unwr;
81: nblocks -= unwr;
82: PROGRESS
83: }
84: }
85: time(&t2);
86: t2 -= t1;
87: if(t2 == 0) t2 = 1;
88: printf("%ds: ", t2);
89: if(nblocks){
90: printf("copy buggered up: sbase=%d nblks=%d dbase=%d\n",
91: sbase, nblocks, dbase);
92: it->result = cd->err;
93: return(TCL_ERROR);
94: }
95: printf("%d blocks at %.1fKB/s\n", nb, nb/(float)t2);
96: return(TCL_OK);
97: }
98:
99: static int
100: copy1(int st, int sd, int sb, int n, int dt, int dd, int db, char *err)
101: {
102: struct scsi_cmd cmd;
103: struct scsi_return ret;
104:
105: set6(cmd, 0x18, sd<<5, 0, 0, 20, 0);
106: cmd.data[0] = 0x10; /* copy */
107: cmd.data[1] = 0;
108: cmd.data[2] = 0;
109: cmd.data[3] = 0;
110: cmd.data[4] = (st<<5)|sd;
111: cmd.data[5] = (dt<<5)|dd;
112: cmd.data[6] = 0;
113: cmd.data[7] = 0;
114: cmd.data[8] = n>>24;
115: cmd.data[9] = n>>16;
116: cmd.data[10] = n>>8;
117: cmd.data[11] = n;
118: cmd.data[12] = sb>>24;
119: cmd.data[13] = sb>>16;
120: cmd.data[14] = sb>>8;
121: cmd.data[15] = sb;
122: cmd.data[16] = db>>24;
123: cmd.data[17] = db>>16;
124: cmd.data[18] = db>>8;
125: cmd.data[19] = db;
126: return(s_io(0, &cmd, 20, &ret, 0, err));
127: }
128:
129: static int
130: search(int dr, int lower, int sbase, int n, Searchtype s, char *err)
131: {
132: uchar *cp;
133: struct scsi_return ret;
134:
135: if(n <= 0)
136: return(0);
137: if(n > 256)
138: n = 256;
139: if(sony_media1(dr, sbase, lower, &ret, err))
140: return(-1);
141: for(cp = ret.data; n-- > 0; cp++)
142: if(good[*cp] != s)
143: break;
144: return(cp-ret.data);
145: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.