|
|
1.1 root 1: /*
2: * Base of share memory for UDC is at : 0xff0000
3: *
4: * The following configuration is required on UDC :
5: * SMD : device 0
6: * CMD_fixed : device 2
7: * CMD_removable : device 3
8: * Floppy0 : device 4
9: * Floppy1 : device 5
10: */
11:
12: #define SBR 0
13: #define PGSHIFT 10
14: #include "pte.h"
15: #include "udc.h"
16:
17:
18: /* UDC command packet */
19: struct UDPAC udpac = {
20: 2, 0, 21, 0, 0, 0, 0, SECTSIZ, 0, 0, 0, 3
21: };
22:
23:
24: /* UDC status packet */
25: struct UDSPAC udspac = {
26: 2, 0, 9, 0, 0, 0, 0, 3
27: };
28: long IObase; /* Virtual addrss of UDC shares memory */
29: long Uack; /* Flag polled for UDC acknowlege */
30: long Udone; /* Flag polled for status packet */
31: long Probe = 0; /* If set do not print error message */
32: extern long unused, iob0, iob2, iob4;
33:
34: udc()
35: { register long r12;
36: long oldvec;
37:
38: writes("\n ** UDC test **\n");
39: Probe = 0;
40: m_udc(); /* Map UDC */
41:
42: /* Set handler for UDC interrupt */
43: asm("movab udhdlr,r12");
44: set_handler(UDCVEC,&oldvec,r12);
45:
46: /* Reset UDC controller */
47: if ( udc_reset()==0 ) {
48: writes("\n** Cannot reset UDC controller \n");
49: return; }
50: u_ex();
51: }
52:
53:
54: /* Routine to map UDC
55: */
56: m_udc()
57: { long r12, phys_pg, pte, old_pte, which1;
58:
59: phys_pg = ((UBASE+IOBASE) >> PGSHIFT) & 0x3fffff;
60: /* 1st physical page of UDC in IO space */
61: pte = phys_pg | PG_KW | PG_V | PG_NC;
62: fix_pte(SBR,unused,&old_pte,pte);
63:
64: /* Base addr of common buffer */
65: IObase = (unused << PGSHIFT);
66:
67: asm("mfpr $SLR,r12");
68: r12++;
69: asm("mtpr r12,$SLR");
70: unused++; /* Next unused PTE in system map */
71: }
72:
73:
74:
75: /* *********************
76: Reset UDC controller.
77: *********************
78: */
79: udc_reset()
80: { register long cnt;
81:
82: IPC_RESET;
83: DELAY(0x1f0000); /* Wait for 3 seconds */
84: cnt = RETRY;
85: while (RD_MCSENT != READY)
86: { DELAY(0x40000);
87: if (--cnt == 0) return(0); }
88: return(1);
89: }
90:
91:
92: /* *********************************
93: Routine to copy from disk to disk
94: *********************************
95: */
96: cpy_dd(sdev, ddev, sblk, dblk, noblk)
97: char sdev, ddev;
98: long sblk, dblk, noblk;
99: {
100: long s_begsec, d_begsec;
101: long ndatablks, s_nsblk, d_nsblk, blk;
102:
103: for(blk=sblk;blk<=(sblk+noblk);blk++)
104: {
105: /* Read 1 block (1K) of data */
106: if (disk_rw(READ,sdev,blk,1,&iob0)==0) return(0);
107: else writec('R');
108:
109: /* Write data */
110: if (disk_rw(WRITE,ddev,dblk,1,&iob0)==0) return(0);
111: else { writec('W');
112: dblk++; }
113: }
114: }
115:
116:
117:
118: /*
119: ******************************************
120: Routine to read/write N block from/to disk
121: ******************************************
122: */
123: disk_rw(op,dev,blkno,no_blks,buf_adr)
124: char op, dev;
125: long no_blks, blkno;
126: char *buf_adr;
127: { long begsec;
128: long nblks, nsblk;
129:
130: nblks = (no_blks*BLKSIZ)/UDC_BLKLEN; /* no of blocks to be read */
131: nsblk = BLKSIZ/SECTSIZ; /* no of sects/logical blk on dev */
132:
133: begsec = (long)(blkno * nsblk); /* begin sector no. */
134: if (op==READ) {
135: writec('.');
136: return(disk_op(dev,UDREAD,UDWTRY,nblks,buf_adr,begsec));
137: }
138: else {
139: writec(',');
140: return(disk_op(dev,UDWRITE,UDWCMP,nblks,buf_adr,begsec));
141: }
142: }
143:
144:
145: /*
146: **********************************************************
147: Routine to set up, sent command packet to UDC and check
148: status packet received from UDC. Return 0 if error occured
149: **********************************************************
150: */
151: disk_op(disk_no,cmd,func,noblk,buf_adr,beg_sctno)
152: char cmd, disk_no, func;
153: long noblk;
154: char *buf_adr;
155: long beg_sctno;
156: {
157:
158: udpac.pkdev = disk_no;
159: udpac.pkcmd = cmd;
160: udpac.pkfnc = func;
161: udpac.pkcnt = noblk;
162: udpac.pbsiz = UDC_BLKLEN; /* 256 for UDC/FDC */
163:
164: udpac.pkmem[0] = (short)(((long)buf_adr >> 16) & 0xffff);
165: udpac.pkmem[1] = (short)((long)buf_adr & 0xffff);
166:
167: udpac.psecno[0] = (short)((beg_sctno >> 16) & 0xffff);
168: udpac.psecno[1] = (short)(beg_sctno & 0xffff);
169: udpac.etx = (char)0x3;
170:
171: return(TP((char *)&udpac,disk_no));
172: }
173:
174:
175: /* ******************************************************
176: Transfer a 21 bytes packet to the controller.
177: the message is written to odd addresses, starting from
178: the given address.
179: ******************************************************
180: */
181: movep21(src, dest,cnt)
182: char *src, *dest;
183: int cnt;
184: {
185: for (; cnt>0; cnt--) {
186: *dest++ = *src++;
187: dest++;
188: }
189: }
190:
191:
192:
193: /* ***************************************
194: Read status packet from the controller.
195: Only read from odd addresses.
196: ***************************************
197: */
198: rdspac(src, dest,cnt)
199: char *src, *dest;
200: int cnt;
201: {
202: for (; cnt>0; cnt--) {
203: *dest++ = *src++;
204: src++;
205: }
206: }
207:
208:
209: /* ******************************************************
210: Transmit packet UDC controller and check return status
211: ******************************************************
212: */
213: TP(packet,disk_no)
214: char *packet, disk_no;
215: { long cnt, retry;
216: char *src, ack, stat, get_ack(), chk_stat();
217:
218: cnt = retry = 0;
219: again:
220: Uack = Udone = 0;
221: if (udc_ready()) sent_pck(packet);
222: else { writes("\nUDC not ready, did a reset..");
223: return(0); }
224: switch (ack = get_ack()) {
225: case PCK_OK : break;
226: case RETRANS : { if (++cnt<10) goto again;
227: else { writes("IPC ack error\n");
228: return(0); }
229: }
230: default : { writes("\ndid not get ACK\n");
231: return(0); }
232: }
233: wtspk:
234: if (stat_wait()==0) { /* Wait for status packet */
235: IPC_RESET;
236: return(0); }
237: rdspac((char *)IPC_PCK,(char *)&udspac,9); /* Get packet */
238:
239: switch (stat=chk_stat(disk_no)) {
240: case 0 : break;
241: case 1 : {
242: writes("\nTP : unsolicited status packet !");
243: prt_stat();
244: goto invlspk; }
245: case 2 : {
246: writes("\nTP : unexpected dev_no in status_pkt !");
247: prt_stat();
248: goto invlspk; }
249: case 3 : {
250: if (!Probe) {
251: writes("\nTP : command didnot complete !");
252: prt_stat(); }
253: goto end; }
254: }
255: ipc_ack(PCK_OK);
256: return(1);
257: invlspk:
258: if ((++retry) > 10) goto end; /* Too many errors */
259: ipc_ack(RETRANS); /* Retransmit packet */
260: goto wtspk; /* go wait for status packet */
261: end:
262: ipc_ack(PCK_OK);
263: return(0);
264: }
265:
266:
267: /* ***************************
268: Routine to get ACK from UDC
269: ***************************
270: */
271: char get_ack()
272: { char ack;
273: register long cnt;
274:
275: cnt = 0xfff00;
276: while (Uack==0) { /* Wait for Ack */
277: if (--cnt <= 0) {
278: writes("\ntime out on Uack..\n");
279: return(0); }
280: }
281: ack=RD_IPCACK;
282: if ((ack==PCK_OK) || (ack==RETRANS)) return(ack); /* received ACK */
283: return(0);
284: }
285:
286: /* ******************************************
287: Routine to poll for status packet from UDC
288: ******************************************
289: */
290: stat_wait()
291: { register long cnt;
292:
293: cnt = 0xfff00;
294: while (!Udone) { /* Wait for completion interrupt */
295: if (--cnt <= 0) {
296: writes("\ntime out on Udone..\n");
297: return(0); }
298: }
299: return(1);
300: }
301:
302:
303: /* ****************************************
304: Routine to check status packet from UDC
305: return 0 : status OK; command completed
306: 1 : Unsolicited packet
307: 2 : Status from unexpected device
308: 3 : Command did not completed
309: ****************************************
310: */
311: char chk_stat(devno)
312: char devno;
313: {
314: if (udspac.id == (char)0xff) return((char)1); /* unsolicited packet */
315: if (udspac.dev != devno) return((char)2);
316: if ((udspac.stype!=0x70) || (udspac.stat!=0)) return((char)3);
317: return((char)0);
318: }
319:
320: /* ***********************
321: Routine to print status
322: ***********************
323: */
324: prt_stat()
325: {
326: writes("\nDevice no. : "); writeh((long)udspac.dev);
327: writes("\nStatus type : ");
328: writeh((long)udspac.stype);
329: writes("\nStatus code : ");
330: writeh((long)udspac.stat);
331: writec('\n');
332: }
333:
334:
335: /* **************************************
336: Routine to sent a command paket to UDC
337: **************************************
338: */
339: sent_pck(packet)
340: char *packet;
341: {
342: movep21(packet, (char *)MC_PCK,21);
343: WR_MCSENT(0x80); /* User packet placed */
344: WR_IPCACK(0); /* Reset for results of packet format test by IPC */
345: IPC_INT; /* Interrupt IPC */
346: }
347:
348: /* **************************************************
349: Routine to check if UDC is ready to receive packet
350: if not then reset UDC and return 0
351: **************************************************
352: */
353: udc_ready()
354: { long cnt;
355:
356: cnt = RETRY;
357: while (RD_MCSENT != READY)
358: { DELAY(1000);
359: if (--cnt==0) { writes("\nTP : time out\n"); goto end; }
360: }
361: return(1);
362: end:
363: IPC_RESET;
364: return(0);
365: }
366:
367: /* *****************************************************
368: Routine to acknowlege status packet received from UDC
369: *****************************************************
370: */
371: ipc_ack(stat)
372: char stat;
373: {
374: WR_IPCSENT(0); /* Packet processed */
375: WR_MCACK(stat); /* Packet status */
376: IPC_INT;
377: }
378:
379: /* UDC interrupt handler
380: */
381: ud_hdlr()
382: {
383: if (RD_IPCACK != 0) { Uack = 1; /* received ACK */
384: }
385: if ((RD_IPCSENT&0xff) == 0x80) {
386: Udone = 1; /* Status packet placed */
387: }
388: }
389:
390: Udchdlr()
391: { long dummy;
392: asm(".align 2");
393: asm("udhdlr:");
394: asm("svpctx");
395: ud_hdlr(); /* UDC handler */
396: asm("ldpctx");
397: asm("rei");
398: }
399:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.