1 |
|
/* |
2 |
|
* ether_amiga.cpp - Ethernet device driver, AmigaOS specific stuff |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-1999 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2001 Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
25 |
|
#include <dos/dosextens.h> |
26 |
|
#include <dos/dostags.h> |
27 |
|
#include <devices/sana2.h> |
28 |
+ |
#define __USE_SYSBASE |
29 |
|
#include <proto/exec.h> |
30 |
|
#include <proto/dos.h> |
31 |
+ |
#include <inline/exec.h> |
32 |
+ |
#include <inline/dos.h> |
33 |
+ |
#include <clib/alib_protos.h> |
34 |
|
|
35 |
|
#include "sysdeps.h" |
36 |
|
#include "cpu_emulation.h" |
120 |
|
* Initialization |
121 |
|
*/ |
122 |
|
|
123 |
< |
void EtherInit(void) |
123 |
> |
bool ether_init(void) |
124 |
|
{ |
125 |
|
// Do nothing if no Ethernet device specified |
126 |
|
if (PrefsFindString("ether") == NULL) |
127 |
< |
return; |
127 |
> |
return false; |
128 |
|
|
129 |
|
// Initialize protocol list |
130 |
|
NewList(&prot_list); |
139 |
|
proc_error = false; |
140 |
|
SetSignal(0, SIGF_SINGLE); |
141 |
|
net_proc = CreateNewProcTags( |
142 |
< |
NP_Entry, net_func, |
143 |
< |
NP_Name, "Basilisk II Ethernet Task", |
142 |
> |
NP_Entry, (ULONG)net_func, |
143 |
> |
NP_Name, (ULONG)"Basilisk II Ethernet Task", |
144 |
|
NP_Priority, 1, |
145 |
|
TAG_END |
146 |
|
); |
155 |
|
goto open_error; |
156 |
|
|
157 |
|
// Everything OK |
158 |
< |
net_open = true; |
155 |
< |
return; |
158 |
> |
return true; |
159 |
|
|
160 |
|
open_error: |
161 |
|
net_proc = NULL; |
163 |
|
DeleteMsgPort(reply_port); |
164 |
|
reply_port = NULL; |
165 |
|
} |
166 |
+ |
return false; |
167 |
|
} |
168 |
|
|
169 |
|
|
171 |
|
* Deinitialization |
172 |
|
*/ |
173 |
|
|
174 |
< |
void EtherExit(void) |
174 |
> |
void ether_exit(void) |
175 |
|
{ |
176 |
|
// Stop process |
177 |
|
if (net_proc) { |
192 |
|
* Reset |
193 |
|
*/ |
194 |
|
|
195 |
< |
void EtherReset(void) |
195 |
> |
void ether_reset(void) |
196 |
|
{ |
197 |
|
// Remove all protocols |
198 |
< |
if (net_open) |
198 |
> |
if (net_proc) |
199 |
|
send_to_proc(MSG_CLEANUP); |
200 |
|
} |
201 |
|
|
291 |
|
* Copy received network packet to Mac side |
292 |
|
*/ |
293 |
|
|
294 |
< |
static __saveds __asm LONG copy_to_buff(register __a0 uint8 *to, register __a1 uint8 *from, register __d0 uint32 packet_len) |
294 |
> |
static __saveds __regargs LONG copy_to_buff(uint8 *to /*a0*/, uint8 *from /*a1*/, uint32 packet_len /*d0*/) |
295 |
|
{ |
296 |
|
D(bug("CopyToBuff to %08lx, from %08lx, size %08lx\n", to, from, packet_len)); |
297 |
|
|
317 |
|
* Copy data from Mac WDS to outgoing network packet |
318 |
|
*/ |
319 |
|
|
320 |
< |
static __saveds __asm LONG copy_from_buff(register __a0 uint8 *to, register __a1 uint32 wds, register __d0 uint32 packet_len) |
320 |
> |
static __saveds __regargs LONG copy_from_buff(uint8 *to /*a0*/, char *wds /*a1*/, uint32 packet_len /*d0*/) |
321 |
|
{ |
322 |
|
D(bug("CopyFromBuff to %08lx, wds %08lx, size %08lx\n", to, wds, packet_len)); |
323 |
|
#if MONITOR |
324 |
|
bug("Sending Ethernet packet:\n"); |
325 |
|
#endif |
326 |
|
for (;;) { |
327 |
< |
int len = ReadMacInt16(wds); |
327 |
> |
int len = ReadMacInt16((uint32)wds); |
328 |
|
if (len == 0) |
329 |
|
break; |
330 |
|
#if MONITOR |
331 |
< |
uint8 *adr = Mac2HostAddr(ReadMacInt32(wds + 2)); |
331 |
> |
uint8 *adr = Mac2HostAddr(ReadMacInt32((uint32)wds + 2)); |
332 |
|
for (int i=0; i<len; i++) { |
333 |
|
bug("%02lx ", adr[i]); |
334 |
|
} |
335 |
|
#endif |
336 |
< |
CopyMem(Mac2HostAddr(ReadMacInt32(wds + 2)), to, len); |
336 |
> |
CopyMem(Mac2HostAddr(ReadMacInt32((uint32)wds + 2)), to, len); |
337 |
|
to += len; |
338 |
|
wds += 6; |
339 |
|
} |
350 |
|
|
351 |
|
static __saveds void net_func(void) |
352 |
|
{ |
353 |
+ |
const char *str; |
354 |
+ |
BYTE od_error; |
355 |
|
struct MsgPort *write_port = NULL, *control_port = NULL; |
356 |
|
struct IOSana2Req *write_io = NULL, *control_io = NULL; |
357 |
|
bool opened = false; |
394 |
|
// Parse device name |
395 |
|
char dev_name[256]; |
396 |
|
ULONG dev_unit; |
397 |
< |
if (sscanf(PrefsFindString("ether"), "%[^/]/%ld", dev_name, &dev_unit) < 2) |
397 |
> |
|
398 |
> |
str = PrefsFindString("ether"); |
399 |
> |
if (str) { |
400 |
> |
const char *FirstSlash = strchr(str, '/'); |
401 |
> |
const char *LastSlash = strrchr(str, '/'); |
402 |
> |
|
403 |
> |
if (FirstSlash && FirstSlash && FirstSlash != LastSlash) { |
404 |
> |
|
405 |
> |
// Device name contains path, i.e. "Networks/xyzzy.device" |
406 |
> |
const char *lp = str; |
407 |
> |
char *dp = dev_name; |
408 |
> |
|
409 |
> |
while (lp != LastSlash) |
410 |
> |
*dp++ = *lp++; |
411 |
> |
*dp = '\0'; |
412 |
> |
|
413 |
> |
if (strlen(dev_name) < 1) |
414 |
> |
goto quit; |
415 |
> |
|
416 |
> |
if (sscanf(LastSlash, "/%ld", &dev_unit) != 1) |
417 |
> |
goto quit; |
418 |
> |
} else { |
419 |
> |
if (sscanf(str, "%[^/]/%ld", dev_name, &dev_unit) != 2) |
420 |
> |
goto quit; |
421 |
> |
} |
422 |
> |
} else |
423 |
|
goto quit; |
424 |
|
|
425 |
|
// Open device |
426 |
|
control_io->ios2_BufferManagement = buffer_tags; |
427 |
< |
if (OpenDevice((UBYTE *)dev_name, dev_unit, (struct IORequest *)control_io, 0) || control_io->ios2_Req.io_Device == 0) |
427 |
> |
od_error = OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)control_io, 0); |
428 |
> |
if (od_error != 0 || control_io->ios2_Req.io_Device == 0) { |
429 |
> |
printf("WARNING: OpenDevice(<%s>, unit=%d) returned error %d)\n", (UBYTE *)dev_name, dev_unit, od_error); |
430 |
|
goto quit; |
431 |
+ |
} |
432 |
|
opened = true; |
433 |
|
|
434 |
|
// Is it Ethernet? |
485 |
|
|
486 |
|
case MSG_ADD_MULTI: |
487 |
|
control_io->ios2_Req.io_Command = S2_ADDMULTICASTADDRESS; |
488 |
< |
memcpy(control_io->ios2_SrcAddr, Mac2HostAddr(msg->pointer + eMultiAddr), 6); |
488 |
> |
Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); |
489 |
|
DoIO((struct IORequest *)control_io); |
490 |
|
if (control_io->ios2_Req.io_Error == S2ERR_NOT_SUPPORTED) { |
491 |
|
WarningAlert(GetString(STR_NO_MULTICAST_WARN)); |
498 |
|
|
499 |
|
case MSG_DEL_MULTI: |
500 |
|
control_io->ios2_Req.io_Command = S2_DELMULTICASTADDRESS; |
501 |
< |
memcpy(control_io->ios2_SrcAddr, Mac2HostAddr(msg->pointer + eMultiAddr), 6); |
501 |
> |
Mac2Host_memcpy(control_io->ios2_SrcAddr, msg->pointer + eMultiAddr, 6); |
502 |
|
DoIO((struct IORequest *)control_io); |
503 |
|
if (control_io->ios2_Req.io_Error) |
504 |
|
msg->result = eMultiErr; |
582 |
|
} |
583 |
|
write_io->ios2_DataLength = len; |
584 |
|
|
585 |
< |
// Get destination address, set source address |
585 |
> |
// Get destination address |
586 |
|
uint32 hdr = ReadMacInt32(wds + 2); |
587 |
< |
memcpy(write_io->ios2_DstAddr, Mac2HostAddr(hdr), 6); |
554 |
< |
memcpy(Mac2HostAddr(hdr + 6), ether_addr, 6); |
587 |
> |
Mac2Host_memcpy(write_io->ios2_DstAddr, hdr, 6); |
588 |
|
|
589 |
|
// Get packet type |
590 |
|
uint32 type = ReadMacInt16(hdr + 12); |
668 |
|
|
669 |
|
// Packet write done, enqueue DT to call IODone |
670 |
|
if (write_done) { |
671 |
< |
Enqueue(ether_data + ed_DeferredTask, 0xd92); |
671 |
> |
EnqueueMac(ether_data + ed_DeferredTask, 0xd92); |
672 |
|
write_done = false; |
673 |
|
} |
674 |
|
|
684 |
|
continue; |
685 |
|
|
686 |
|
// Copy header to RHA |
687 |
< |
memcpy(Mac2HostAddr(ether_data + ed_RHA), io->ios2_Data, 14); |
687 |
> |
Host2Mac_memcpy(ether_data + ed_RHA, io->ios2_Data, 14); |
688 |
|
D(bug(" header %08lx%04lx %08lx%04lx %04lx\n", ReadMacInt32(ether_data + ed_RHA), ReadMacInt16(ether_data + ed_RHA + 4), ReadMacInt32(ether_data + ed_RHA + 6), ReadMacInt16(ether_data + ed_RHA + 10), ReadMacInt16(ether_data + ed_RHA + 12))); |
689 |
|
|
690 |
|
// Call protocol handler |