fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

macplus: Move DaynaPORT functionality to scsi_dynaport.c

In case there are other network implementations later.

+329 -327
+2 -2
src/arch/macplus/Makefile.inc
··· 51 51 msg \ 52 52 rtc \ 53 53 scsi \ 54 - scsi_net \ 54 + scsi_daynaport \ 55 55 serial \ 56 56 sony \ 57 57 sound \ ··· 131 131 $(rel)/msg.o: $(rel)/msg.c 132 132 $(rel)/rtc.o: $(rel)/rtc.c 133 133 $(rel)/scsi.o: $(rel)/scsi.c 134 - $(rel)/scsi_net.o: $(rel)/scsi_net.c 134 + $(rel)/scsi_daynaport.o: $(rel)/scsi_daynaport.c 135 135 $(rel)/serial.o: $(rel)/serial.c 136 136 $(rel)/sony.o: $(rel)/sony.c 137 137 $(rel)/sound.o: $(rel)/sound.c
+8 -8
src/arch/macplus/macplus.c
··· 1116 1116 ini_sct_t *sct, *sctdev; 1117 1117 mem_blk_t *blk; 1118 1118 unsigned long addr, size; 1119 - unsigned id, drive, ethernet; 1119 + unsigned id, drive, daynaport; 1120 1120 const char *vendor, *product, *mac_addr, *tap_dev, *tap_cmd, *bridge_if; 1121 1121 1122 1122 sct = ini_next_sct (ini, NULL, "scsi"); ··· 1154 1154 while (sctdev != NULL) { 1155 1155 ini_get_uint16 (sctdev, "id", &id, 0); 1156 1156 ini_get_uint16 (sctdev, "drive", &drive, 0); 1157 - ini_get_uint16 (sctdev, "ethernet", &ethernet, 0); 1157 + ini_get_uint16 (sctdev, "daynaport", &daynaport, 0); 1158 1158 1159 1159 if (drive) { 1160 1160 ini_get_string (sctdev, "vendor", &vendor, "PCE"); ··· 1170 1170 mac_scsi_set_drive_vendor (&sim->scsi, id, vendor); 1171 1171 mac_scsi_set_drive_product (&sim->scsi, id, product); 1172 1172 } 1173 - else if (ethernet) { 1173 + else if (daynaport) { 1174 1174 ini_get_string (sctdev, "tap", &tap_dev, "/dev/tap0"); 1175 1175 ini_get_string (sctdev, "tap_cmd", &tap_cmd, ""); 1176 1176 ini_get_string (sctdev, "mac_addr", &mac_addr, "00:80:19:c0:ff:ee"); ··· 1179 1179 pce_log_tag (MSG_INF, 1180 1180 "SCSI:", 1181 1181 #if PCE_ENABLE_VMNET 1182 - "id=%u ethernet=%u bridge=%s mac_addr=%s\n", 1183 - id, ethernet, bridge_if, mac_addr 1182 + "id=%u daynaport=%u bridge=%s mac_addr=%s\n", 1183 + id, daynaport, bridge_if, mac_addr 1184 1184 #else 1185 - "id=%u ethernet=%u tap=%s cmd=%s mac_addr=%s\n", 1186 - id, ethernet, tap_dev, tap_cmd, mac_addr 1185 + "id=%u daynaport=%u tap=%s cmd=%s mac_addr=%s\n", 1186 + id, daynaport, tap_dev, tap_cmd, mac_addr 1187 1187 #endif 1188 1188 ); 1189 1189 1190 - mac_scsi_set_ethernet (&sim->scsi, id, tap_dev, tap_cmd, mac_addr, bridge_if); 1190 + mac_scsi_set_daynaport (&sim->scsi, id, tap_dev, tap_cmd, mac_addr, bridge_if); 1191 1191 } 1192 1192 1193 1193 sctdev = ini_next_sct (sct, sctdev, "device");
+6 -6
src/arch/macplus/pce-macplus.cfg.in
··· 306 306 # DaynaPORT SCSI/Link device emulation on SCSI id 3. 307 307 # Requires read/write access on the "tap" device listed here. 308 308 #device { 309 - # id = 3 310 - # ethernet = 1 311 - # tap = "/dev/tap0" # OpenBSD 312 - # tap = "/dev/net/tun" # Linux 313 - # mac_addr = "00:80:19:c0:ff:ee" 309 + # id = 3 310 + # daynaport = 1 311 + # tap = "/dev/tap0" # OpenBSD 312 + # tap = "/dev/net/tun" # Linux 313 + # mac_addr = "00:80:19:c0:ff:ee" 314 314 # 315 315 # # This command will be run after initializing the tap device 316 316 # # and will have the tap device and MAC address passed as 317 317 # # arguments. It should probably assign an IP to this tap 318 318 # # device if using NAT (required on WiFi), or setup bridging 319 319 # # if using ethernet. 320 - # tap_cmd = "sh /etc/pce/tap-setup.sh" 320 + # tap_cmd = "sh /etc/pce/tap-setup.sh" 321 321 #} 322 322 } 323 323
+29 -168
src/arch/macplus/scsi.c
··· 191 191 } 192 192 } 193 193 194 - void mac_scsi_set_ethernet (mac_scsi_t *scsi, unsigned id, const char *tap_dev, const char *tap_cmd, const char *mac_addr, const char *bridge_if) 195 - { 196 - int mac_addr_ints[6]; 197 - int ret; 198 - 199 - id &= 7; 200 - 201 - scsi->dev[id].valid = 0; 202 - scsi->dev[id].type = MAC_SCSI_DEV_ETHERNET; 203 - 204 - memcpy (scsi->dev[id].vendor, "Dayna ", 8); 205 - memcpy (scsi->dev[id].product, "SCSI/Link ", 16); 206 - memcpy (scsi->dev[id].revision, "2.0f", 4); 207 - 208 - strncpy (scsi->dev[id].tap_dev, tap_dev, sizeof(scsi->dev[id].tap_dev)); 209 - strncpy (scsi->dev[id].tap_cmd, tap_cmd, sizeof(scsi->dev[id].tap_cmd)); 210 - #if PCE_ENABLE_VMNET 211 - strncpy (scsi->dev[id].bridge_if, bridge_if, sizeof(scsi->dev[id].bridge_if)); 212 - #endif 213 - 214 - ret = sscanf(mac_addr, "%x:%x:%x:%x:%x:%x", 215 - &mac_addr_ints[0], &mac_addr_ints[1], 216 - &mac_addr_ints[2], &mac_addr_ints[3], 217 - &mac_addr_ints[4], &mac_addr_ints[5]); 218 - if (ret == 6) { 219 - for (int i = 0; i <= 5; i++) 220 - scsi->dev[id].mac_addr[i] = mac_addr_ints[i] & 0xff; 221 - } else { 222 - pce_log (MSG_ERR, "*** invalid MAC address (%s)\n", mac_addr); 223 - } 224 - 225 - if (mac_scsi_ethernet_open (scsi, &scsi->dev[id]) == 0) { 226 - scsi->dev[id].valid = 1; 227 - } 228 - } 229 - 230 194 static 231 195 int mac_scsi_set_buf_max (mac_scsi_t *scsi, unsigned long max) 232 196 { ··· 348 312 scsi->cmd_n = 16; 349 313 } 350 314 351 - static 352 315 void mac_scsi_set_phase_data_in (mac_scsi_t *scsi) 353 316 { 354 317 #ifdef DEBUG_SCSI ··· 366 329 scsi->csd = scsi->buf[scsi->buf_i]; 367 330 } 368 331 369 - static 370 332 void mac_scsi_set_phase_data_out (mac_scsi_t *scsi) 371 333 { 372 334 #ifdef DEBUG_SCSI ··· 382 344 scsi->csb |= E5380_CSB_REQ; 383 345 } 384 346 385 - static 386 347 void mac_scsi_set_phase_status (mac_scsi_t *scsi, unsigned char val) 387 348 { 388 349 #ifdef DEBUG_SCSI ··· 443 404 #endif 444 405 } 445 406 446 - static 447 407 mac_scsi_dev_t *mac_scsi_get_device (mac_scsi_t *scsi) 448 408 { 449 409 unsigned id; ··· 543 503 544 504 mac_scsi_set_phase_data_in (scsi); 545 505 break; 546 - case MAC_SCSI_DEV_ETHERNET: 506 + case MAC_SCSI_DEV_DAYNAPORT: 547 507 if (cnt == 1) { 548 508 mac_scsi_set_phase_status (scsi, 0x02); 549 509 return; ··· 558 518 559 519 memset (scsi->buf, 0, cnt); 560 520 561 - psize = mac_scsi_ethernet_read (dev, scsi->buf + 6); 521 + psize = mac_scsi_daynaport_read (dev, scsi->buf + 6); 562 522 if (psize > 0) { 563 523 scsi->buf[0] = (psize >> 8) & 0xff; 564 524 scsi->buf[1] = psize & 0xff; 565 525 566 - if (mac_scsi_ethernet_data_avail (dev)) { 526 + if (mac_scsi_daynaport_data_avail (dev)) { 567 527 scsi->buf[5] = 0x10; 568 528 } 569 529 } ··· 655 615 return; 656 616 } 657 617 break; 658 - case MAC_SCSI_DEV_ETHERNET: 618 + case MAC_SCSI_DEV_DAYNAPORT: 659 619 for (;;) { 660 620 if (scsi->cmd[5] == 0x80) { 661 621 cnt = (long)(scsi->buf[0] << 8) | scsi->buf[1]; 662 - mac_scsi_ethernet_write (dev, scsi->buf + 4, cnt); 622 + mac_scsi_daynaport_write (dev, scsi->buf + 4, cnt); 663 623 } else { 664 624 /* XXX: do these non-preamble packets exist? */ 665 - mac_scsi_ethernet_write (dev, scsi->buf, cnt); 625 + mac_scsi_daynaport_write (dev, scsi->buf, cnt); 666 626 break; 667 627 } 668 628 ··· 699 659 mac_scsi_set_phase_status (scsi, 0x00); 700 660 } 701 661 702 - static 703 662 void mac_scsi_cmd_write6_finish (mac_scsi_t *scsi) 704 663 { 705 664 unsigned long lba; ··· 744 703 size = 512UL * cnt; 745 704 break; 746 705 747 - case MAC_SCSI_DEV_ETHERNET: 706 + case MAC_SCSI_DEV_DAYNAPORT: 748 707 size = ((long)(scsi->cmd[3]) << 8) + scsi->cmd[4]; 749 708 750 709 if (scsi->cmd[5] == 0x80) { ··· 848 807 mac_log_deb ("scsi: verify %u blocks at %lu\n", cnt, lba); 849 808 #endif 850 809 break; 851 - case MAC_SCSI_DEV_ETHERNET: 810 + case MAC_SCSI_DEV_DAYNAPORT: 852 811 break; 853 812 } 854 813 ··· 877 836 scsi->buf[0] = 0x00; /* direct-access device */ 878 837 break; 879 838 880 - case MAC_SCSI_DEV_ETHERNET: 839 + case MAC_SCSI_DEV_DAYNAPORT: 881 840 scsi->buf[0] = 0x03; /* processor device */ 882 841 scsi->buf[2] = 0x01; 883 842 break; ··· 966 925 } 967 926 break; 968 927 969 - case MAC_SCSI_DEV_ETHERNET: 928 + case MAC_SCSI_DEV_DAYNAPORT: 970 929 break; 971 930 } 972 931 ··· 1031 990 buf_set_uint32_be (scsi->buf, 4, 512); 1032 991 break; 1033 992 1034 - case MAC_SCSI_DEV_ETHERNET: 993 + case MAC_SCSI_DEV_DAYNAPORT: 1035 994 buf_set_uint32_be (scsi->buf, 0, 1); 1036 995 buf_set_uint32_be (scsi->buf, 4, 512); 1037 996 break; ··· 1055 1014 } 1056 1015 1057 1016 1058 - /* DaynaPort vendor commands */ 1059 - 1060 - static 1061 - void mac_scsi_cmd_read_stats (mac_scsi_t *scsi) 1062 - { 1063 - mac_scsi_dev_t *dev; 1064 - 1065 - dev = mac_scsi_get_device (scsi); 1066 - 1067 - if (dev == NULL || dev->type != MAC_SCSI_DEV_ETHERNET) { 1068 - mac_scsi_set_phase_status (scsi, 0x02); 1069 - return; 1070 - } 1071 - 1072 - memset (scsi->buf, 0, 18); 1073 - 1074 - memcpy(scsi->buf, dev->mac_addr, 6); 1075 - /* three 32-bit counters expected to follow, just return zero for all */ 1076 - 1077 - scsi->buf_i = 0; 1078 - scsi->buf_n = 18; 1079 - 1080 - mac_scsi_set_phase_data_in (scsi); 1081 - } 1082 - 1083 - static 1084 - void mac_scsi_cmd_set_interface_mode (mac_scsi_t *scsi) 1085 - { 1086 - mac_scsi_dev_t *dev; 1087 - unsigned char cmd; 1088 - 1089 - dev = mac_scsi_get_device (scsi); 1090 - 1091 - if (dev == NULL || dev->type != MAC_SCSI_DEV_ETHERNET) { 1092 - mac_scsi_set_phase_status (scsi, 0x02); 1093 - return; 1094 - } 1095 - 1096 - cmd = scsi->cmd[5] & 0x80; 1097 - 1098 - switch (cmd) { 1099 - case 0x40: 1100 - /* set MAC (noop) */ 1101 - scsi->buf_i = 0; 1102 - scsi->buf_n = 6; 1103 - 1104 - scsi->cmd_finish = mac_scsi_cmd_write6_finish; 1105 - 1106 - mac_scsi_set_phase_data_out (scsi); 1107 - break; 1108 - 1109 - case 0x80: 1110 - /* set mode (noop) */ 1111 - mac_scsi_set_phase_status (scsi, 0x02); 1112 - break; 1113 - 1114 - default: 1115 - mac_log_deb ("scsi: unknown interface mode command (%02X)\n", cmd); 1116 - mac_scsi_set_phase_status (scsi, 0x02); 1117 - } 1118 - } 1119 - 1120 - static 1121 - void mac_scsi_cmd_set_mcast_addr (mac_scsi_t *scsi) 1122 - { 1123 - mac_scsi_dev_t *dev; 1124 - 1125 - dev = mac_scsi_get_device (scsi); 1126 - 1127 - if (dev == NULL || dev->type != MAC_SCSI_DEV_ETHERNET) { 1128 - mac_scsi_set_phase_status (scsi, 0x02); 1129 - return; 1130 - } 1131 - 1132 - scsi->buf_i = 0; 1133 - scsi->buf_n = scsi->cmd[4]; 1134 - 1135 - scsi->cmd_finish = mac_scsi_cmd_write6_finish; 1136 - 1137 - mac_scsi_set_phase_data_out (scsi); 1138 - } 1139 - 1140 - static 1141 - void mac_scsi_cmd_enable_interface (mac_scsi_t *scsi) 1142 - { 1143 - mac_scsi_dev_t *dev; 1144 - 1145 - dev = mac_scsi_get_device (scsi); 1146 - 1147 - if (dev == NULL || dev->type != MAC_SCSI_DEV_ETHERNET) { 1148 - mac_scsi_set_phase_status (scsi, 0x02); 1149 - return; 1150 - } 1151 - 1152 - dev->tap_enabled = !!(scsi->cmd[5] & 0x80); 1153 - 1154 - mac_scsi_set_phase_status (scsi, 0x02); 1155 - } 1156 - 1157 - 1158 1017 static 1159 1018 void mac_scsi_set_cmd (mac_scsi_t *scsi, unsigned cnt, void (*cmd) (mac_scsi_t *scsi)) 1160 1019 { ··· 1185 1044 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_read6); 1186 1045 break; 1187 1046 1188 - case 0x09: 1189 - mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_read_stats); 1190 - break; 1191 - 1192 1047 case 0x0a: 1193 1048 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_write6); 1194 1049 break; 1195 1050 1196 - case 0x0c: 1197 - mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_set_interface_mode); 1198 - break; 1199 - 1200 - case 0x0d: 1201 - mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_set_mcast_addr); 1202 - break; 1203 - 1204 - case 0x0e: 1205 - mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_enable_interface); 1206 - break; 1207 - 1208 1051 case 0x12: 1209 1052 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_inquiry); 1210 1053 break; ··· 1239 1082 1240 1083 case 0x3c: 1241 1084 mac_scsi_set_cmd (scsi, 6, mac_scsi_cmd_read_buffer); 1085 + break; 1086 + 1087 + /* DaynaPORT vendor commands */ 1088 + 1089 + case 0x09: 1090 + mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_read_stats); 1091 + break; 1092 + 1093 + case 0x0c: 1094 + mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_set_interface_mode); 1095 + break; 1096 + 1097 + case 0x0d: 1098 + mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_set_mcast_addr); 1099 + break; 1100 + 1101 + case 0x0e: 1102 + mac_scsi_set_cmd (scsi, 6, mac_scsi_daynaport_cmd_enable_interface); 1242 1103 break; 1243 1104 1244 1105 default:
+16 -6
src/arch/macplus/scsi.h
··· 35 35 enum { 36 36 MAC_SCSI_DEV_UNKNOWN, 37 37 MAC_SCSI_DEV_DISK, 38 - MAC_SCSI_DEV_ETHERNET, 38 + MAC_SCSI_DEV_DAYNAPORT, 39 39 }; 40 40 41 41 typedef struct { ··· 109 109 110 110 void mac_scsi_set_int_fct (mac_scsi_t *scsi, void *ext, void *fct); 111 111 112 + mac_scsi_dev_t *mac_scsi_get_device (mac_scsi_t *scsi); 113 + void mac_scsi_set_phase_status (mac_scsi_t *scsi, unsigned char val); 114 + void mac_scsi_set_phase_data_in (mac_scsi_t *scsi); 115 + void mac_scsi_set_phase_data_out (mac_scsi_t *scsi); 116 + void mac_scsi_cmd_write6_finish (mac_scsi_t *scsi); 117 + 112 118 void mac_scsi_set_disks (mac_scsi_t *scsi, disks_t *dsks); 113 119 void mac_scsi_set_drive (mac_scsi_t *scsi, unsigned id, unsigned drive); 114 120 void mac_scsi_set_drive_vendor (mac_scsi_t *scsi, unsigned id, const char *vendor); 115 121 void mac_scsi_set_drive_product (mac_scsi_t *scsi, unsigned id, const char *product); 116 - void mac_scsi_set_ethernet (mac_scsi_t *scsi, unsigned id, const char *tap_dev, const char *tap_cmd, const char *mac_addr, const char *bridge_if); 117 122 118 123 unsigned char mac_scsi_get_uint8 (void *ext, unsigned long addr); 119 124 unsigned short mac_scsi_get_uint16 (void *ext, unsigned long addr); ··· 123 128 124 129 void mac_scsi_reset (mac_scsi_t *scsi); 125 130 126 - int mac_scsi_ethernet_open (mac_scsi_t *scsi, mac_scsi_dev_t *dev); 127 - int mac_scsi_ethernet_data_avail (mac_scsi_dev_t *dev); 128 - size_t mac_scsi_ethernet_read (mac_scsi_dev_t *dev, unsigned char *buf); 129 - size_t mac_scsi_ethernet_write (mac_scsi_dev_t *dev, unsigned char *buf, size_t len); 131 + void mac_scsi_set_daynaport (mac_scsi_t *scsi, unsigned id, const char *tap_dev, const char *tap_cmd, const char *mac_addr, const char *bridge_if); 132 + int mac_scsi_daynaport_open (mac_scsi_t *scsi, mac_scsi_dev_t *dev); 133 + int mac_scsi_daynaport_data_avail (mac_scsi_dev_t *dev); 134 + size_t mac_scsi_daynaport_read (mac_scsi_dev_t *dev, unsigned char *buf); 135 + size_t mac_scsi_daynaport_write (mac_scsi_dev_t *dev, unsigned char *buf, size_t len); 136 + void mac_scsi_daynaport_cmd_read_stats (mac_scsi_t *scsi); 137 + void mac_scsi_daynaport_cmd_set_interface_mode (mac_scsi_t *scsi); 138 + void mac_scsi_daynaport_cmd_set_mcast_addr (mac_scsi_t *scsi); 139 + void mac_scsi_daynaport_cmd_enable_interface (mac_scsi_t *scsi); 130 140 131 141 #endif
+268
src/arch/macplus/scsi_daynaport.c
··· 1 + /***************************************************************************** 2 + * pce * 3 + *****************************************************************************/ 4 + 5 + /***************************************************************************** 6 + * File name: src/arch/macplus/scsi_daynaport.c * 7 + * Created: 2022-05-01 by joshua stein <jcs@jcs.org> * 8 + * Copyright: (C) 2022 joshua stein <jcs@jcs.org> * 9 + *****************************************************************************/ 10 + 11 + /***************************************************************************** 12 + * This program is free software. You can redistribute it and / or modify it * 13 + * under the terms of the GNU General Public License version 2 as published * 14 + * by the Free Software Foundation. * 15 + * * 16 + * This program is distributed in the hope that it will be useful, but * 17 + * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 + * Public License for more details. * 20 + *****************************************************************************/ 21 + 22 + #include "main.h" 23 + #include "scsi.h" 24 + 25 + #include <stdlib.h> 26 + 27 + #include <lib/log.h> 28 + 29 + #include <errno.h> 30 + #include <string.h> 31 + #include <poll.h> 32 + #include <sys/fcntl.h> 33 + #include <sys/types.h> 34 + 35 + void mac_scsi_set_daynaport (mac_scsi_t *scsi, unsigned id, const char *tap_dev, const char *tap_cmd, const char *mac_addr, const char *bridge_if) 36 + { 37 + int mac_addr_ints[6]; 38 + int ret; 39 + 40 + id &= 7; 41 + 42 + scsi->dev[id].valid = 0; 43 + scsi->dev[id].type = MAC_SCSI_DEV_DAYNAPORT; 44 + 45 + memcpy (scsi->dev[id].vendor, "Dayna ", 8); 46 + memcpy (scsi->dev[id].product, "SCSI/Link ", 16); 47 + memcpy (scsi->dev[id].revision, "2.0f", 4); 48 + 49 + strncpy (scsi->dev[id].tap_dev, tap_dev, sizeof(scsi->dev[id].tap_dev)); 50 + strncpy (scsi->dev[id].tap_cmd, tap_cmd, sizeof(scsi->dev[id].tap_cmd)); 51 + #if PCE_ENABLE_VMNET 52 + strncpy (scsi->dev[id].bridge_if, bridge_if, sizeof(scsi->dev[id].bridge_if)); 53 + #endif 54 + 55 + ret = sscanf(mac_addr, "%x:%x:%x:%x:%x:%x", 56 + &mac_addr_ints[0], &mac_addr_ints[1], 57 + &mac_addr_ints[2], &mac_addr_ints[3], 58 + &mac_addr_ints[4], &mac_addr_ints[5]); 59 + if (ret == 6) { 60 + for (int i = 0; i <= 5; i++) 61 + scsi->dev[id].mac_addr[i] = mac_addr_ints[i] & 0xff; 62 + } else { 63 + pce_log (MSG_ERR, "*** invalid MAC address (%s)\n", mac_addr); 64 + } 65 + 66 + if (mac_scsi_daynaport_open (scsi, &scsi->dev[id]) == 0) { 67 + scsi->dev[id].valid = 1; 68 + } 69 + } 70 + 71 + int mac_scsi_daynaport_open (mac_scsi_t *scsi, mac_scsi_dev_t *dev) 72 + { 73 + #if PCE_ENABLE_VMNET 74 + dev->vmnet = pce_vmnet_start (dev->bridge_if); 75 + if (dev->vmnet == NULL) { 76 + pce_log (MSG_ERR, "*** failed creating vmnet interface\n"); 77 + return - 1; 78 + } 79 + #else 80 + char tap_cmd_sh[1024]; 81 + 82 + dev->tap_fd = -1; 83 + 84 + if (dev->tap_cmd[0] != '\0') { 85 + /* run command with args "/dev/tap0" "00:00:00:00:00:00" */ 86 + snprintf (tap_cmd_sh, sizeof(tap_cmd_sh), "%s \"%s\" \"%02x:%02x:%02x:%02x:%02x:%02x\"", 87 + dev->tap_cmd, dev->tap_dev, 88 + dev->mac_addr[0], dev->mac_addr[1], 89 + dev->mac_addr[2], dev->mac_addr[3], 90 + dev->mac_addr[4], dev->mac_addr[5]); 91 + pce_log_tag (MSG_INF, 92 + "SCSI:", 93 + "running tap command: %s\n", 94 + tap_cmd_sh); 95 + 96 + if (system (tap_cmd_sh) != 0) { 97 + pce_log (MSG_ERR, "*** tap command failed (%s)\n", strerror(errno)); 98 + } 99 + } 100 + 101 + if ((dev->tap_fd = open (dev->tap_dev, O_RDWR)) < 0) { 102 + pce_log (MSG_ERR, "*** opening %s failed (%s)\n", dev->tap_dev, strerror(errno)); 103 + return - 1; 104 + } 105 + #endif 106 + 107 + return 0; 108 + } 109 + 110 + int mac_scsi_daynaport_data_avail (mac_scsi_dev_t *dev) 111 + { 112 + struct pollfd fds; 113 + 114 + #if PCE_ENABLE_VMNET 115 + if (dev->vmnet == NULL) 116 + return 0; 117 + return (dev->vmnet->packets_available > 0 ? 1 : 0); 118 + #else 119 + fds.fd = dev->tap_fd; 120 + fds.events = POLLIN | POLLERR; 121 + if (poll (&fds, 1, 0) < 1) { 122 + return 0; 123 + } 124 + if ((fds.revents & POLLIN)) { 125 + return 1; 126 + } 127 + 128 + return 0; 129 + #endif 130 + } 131 + 132 + size_t mac_scsi_daynaport_read (mac_scsi_dev_t *dev, unsigned char *buf) 133 + { 134 + #if PCE_ENABLE_VMNET 135 + size_t ret; 136 + 137 + if (dev->vmnet == NULL) 138 + return 0; 139 + 140 + ret = pce_vmnet_read(dev->vmnet, buf, 1514); 141 + if (ret == 0) 142 + dev->vmnet->packets_available = 0; 143 + return ret; 144 + #else 145 + if (dev->tap_fd < 0) { 146 + return 0; 147 + } 148 + 149 + if (!mac_scsi_daynaport_data_avail (dev)) { 150 + return 0; 151 + } 152 + 153 + return read (dev->tap_fd, buf, 1514); 154 + #endif 155 + } 156 + 157 + size_t mac_scsi_daynaport_write (mac_scsi_dev_t *dev, unsigned char *buf, size_t len) 158 + { 159 + #if PCE_ENABLE_VMNET 160 + size_t ret; 161 + 162 + if (dev->vmnet == NULL) 163 + return 0; 164 + 165 + return (pce_vmnet_write(dev->vmnet, buf, len) == 0 ? len : 0); 166 + #else 167 + if (dev->tap_fd < 0) { 168 + return 0; 169 + } 170 + 171 + return write (dev->tap_fd, buf, len); 172 + #endif 173 + } 174 + 175 + /* DaynaPORT vendor commands */ 176 + 177 + void mac_scsi_daynaport_cmd_read_stats (mac_scsi_t *scsi) 178 + { 179 + mac_scsi_dev_t *dev; 180 + 181 + dev = mac_scsi_get_device (scsi); 182 + 183 + if (dev == NULL || dev->type != MAC_SCSI_DEV_DAYNAPORT) { 184 + mac_scsi_set_phase_status (scsi, 0x02); 185 + return; 186 + } 187 + 188 + memset (scsi->buf, 0, 18); 189 + 190 + memcpy(scsi->buf, dev->mac_addr, 6); 191 + /* three 32-bit counters expected to follow, just return zero for all */ 192 + 193 + scsi->buf_i = 0; 194 + scsi->buf_n = 18; 195 + 196 + mac_scsi_set_phase_data_in (scsi); 197 + } 198 + 199 + void mac_scsi_daynaport_cmd_set_interface_mode (mac_scsi_t *scsi) 200 + { 201 + mac_scsi_dev_t *dev; 202 + unsigned char cmd; 203 + 204 + dev = mac_scsi_get_device (scsi); 205 + 206 + if (dev == NULL || dev->type != MAC_SCSI_DEV_DAYNAPORT) { 207 + mac_scsi_set_phase_status (scsi, 0x02); 208 + return; 209 + } 210 + 211 + cmd = scsi->cmd[5] & 0x80; 212 + 213 + switch (cmd) { 214 + case 0x40: 215 + /* set MAC (noop) */ 216 + scsi->buf_i = 0; 217 + scsi->buf_n = 6; 218 + 219 + scsi->cmd_finish = mac_scsi_cmd_write6_finish; 220 + 221 + mac_scsi_set_phase_data_out (scsi); 222 + break; 223 + 224 + case 0x80: 225 + /* set mode (noop) */ 226 + mac_scsi_set_phase_status (scsi, 0x02); 227 + break; 228 + 229 + default: 230 + mac_log_deb ("scsi: unknown interface mode command (%02X)\n", cmd); 231 + mac_scsi_set_phase_status (scsi, 0x02); 232 + } 233 + } 234 + 235 + void mac_scsi_daynaport_cmd_set_mcast_addr (mac_scsi_t *scsi) 236 + { 237 + mac_scsi_dev_t *dev; 238 + 239 + dev = mac_scsi_get_device (scsi); 240 + 241 + if (dev == NULL || dev->type != MAC_SCSI_DEV_DAYNAPORT) { 242 + mac_scsi_set_phase_status (scsi, 0x02); 243 + return; 244 + } 245 + 246 + scsi->buf_i = 0; 247 + scsi->buf_n = scsi->cmd[4]; 248 + 249 + scsi->cmd_finish = mac_scsi_cmd_write6_finish; 250 + 251 + mac_scsi_set_phase_data_out (scsi); 252 + } 253 + 254 + void mac_scsi_daynaport_cmd_enable_interface (mac_scsi_t *scsi) 255 + { 256 + mac_scsi_dev_t *dev; 257 + 258 + dev = mac_scsi_get_device (scsi); 259 + 260 + if (dev == NULL || dev->type != MAC_SCSI_DEV_DAYNAPORT) { 261 + mac_scsi_set_phase_status (scsi, 0x02); 262 + return; 263 + } 264 + 265 + dev->tap_enabled = !!(scsi->cmd[5] & 0x80); 266 + 267 + mac_scsi_set_phase_status (scsi, 0x02); 268 + }
-137
src/arch/macplus/scsi_net.c
··· 1 - /***************************************************************************** 2 - * pce * 3 - *****************************************************************************/ 4 - 5 - /***************************************************************************** 6 - * File name: src/arch/macplus/scsi_net.c * 7 - * Created: 2022-05-01 by joshua stein <jcs@jcs.org> * 8 - * Copyright: (C) 2022 joshua stein <jcs@jcs.org> * 9 - *****************************************************************************/ 10 - 11 - /***************************************************************************** 12 - * This program is free software. You can redistribute it and / or modify it * 13 - * under the terms of the GNU General Public License version 2 as published * 14 - * by the Free Software Foundation. * 15 - * * 16 - * This program is distributed in the hope that it will be useful, but * 17 - * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 - * Public License for more details. * 20 - *****************************************************************************/ 21 - 22 - #include "main.h" 23 - #include "scsi.h" 24 - 25 - #include <stdlib.h> 26 - 27 - #include <lib/log.h> 28 - 29 - #include <errno.h> 30 - #include <string.h> 31 - #include <poll.h> 32 - #include <sys/fcntl.h> 33 - #include <sys/types.h> 34 - 35 - int mac_scsi_ethernet_open (mac_scsi_t *scsi, mac_scsi_dev_t *dev) 36 - { 37 - #if PCE_ENABLE_VMNET 38 - dev->vmnet = pce_vmnet_start (dev->bridge_if); 39 - if (dev->vmnet == NULL) { 40 - pce_log (MSG_ERR, "*** failed creating vmnet interface\n"); 41 - return - 1; 42 - } 43 - #else 44 - char tap_cmd_sh[1024]; 45 - 46 - dev->tap_fd = -1; 47 - 48 - if (dev->tap_cmd[0] != '\0') { 49 - /* run command with args "/dev/tap0" "00:00:00:00:00:00" */ 50 - snprintf (tap_cmd_sh, sizeof(tap_cmd_sh), "%s \"%s\" \"%02x:%02x:%02x:%02x:%02x:%02x\"", 51 - dev->tap_cmd, dev->tap_dev, 52 - dev->mac_addr[0], dev->mac_addr[1], 53 - dev->mac_addr[2], dev->mac_addr[3], 54 - dev->mac_addr[4], dev->mac_addr[5]); 55 - pce_log_tag (MSG_INF, 56 - "SCSI:", 57 - "running tap command: %s\n", 58 - tap_cmd_sh); 59 - 60 - if (system (tap_cmd_sh) != 0) { 61 - pce_log (MSG_ERR, "*** tap command failed (%s)\n", strerror(errno)); 62 - } 63 - } 64 - 65 - if ((dev->tap_fd = open (dev->tap_dev, O_RDWR)) < 0) { 66 - pce_log (MSG_ERR, "*** opening %s failed (%s)\n", dev->tap_dev, strerror(errno)); 67 - return - 1; 68 - } 69 - #endif 70 - 71 - return 0; 72 - } 73 - 74 - int mac_scsi_ethernet_data_avail (mac_scsi_dev_t *dev) 75 - { 76 - struct pollfd fds; 77 - 78 - #if PCE_ENABLE_VMNET 79 - if (dev->vmnet == NULL) 80 - return 0; 81 - return (dev->vmnet->packets_available > 0 ? 1 : 0); 82 - #else 83 - fds.fd = dev->tap_fd; 84 - fds.events = POLLIN | POLLERR; 85 - if (poll (&fds, 1, 0) < 1) { 86 - return 0; 87 - } 88 - if ((fds.revents & POLLIN)) { 89 - return 1; 90 - } 91 - 92 - return 0; 93 - #endif 94 - } 95 - 96 - size_t mac_scsi_ethernet_read (mac_scsi_dev_t *dev, unsigned char *buf) 97 - { 98 - #if PCE_ENABLE_VMNET 99 - size_t ret; 100 - 101 - if (dev->vmnet == NULL) 102 - return 0; 103 - 104 - ret = pce_vmnet_read(dev->vmnet, buf, 1514); 105 - if (ret == 0) 106 - dev->vmnet->packets_available = 0; 107 - return ret; 108 - #else 109 - if (dev->tap_fd < 0) { 110 - return 0; 111 - } 112 - 113 - if (!mac_scsi_ethernet_data_avail (dev)) { 114 - return 0; 115 - } 116 - 117 - return read (dev->tap_fd, buf, 1514); 118 - #endif 119 - } 120 - 121 - size_t mac_scsi_ethernet_write (mac_scsi_dev_t *dev, unsigned char *buf, size_t len) 122 - { 123 - #if PCE_ENABLE_VMNET 124 - size_t ret; 125 - 126 - if (dev->vmnet == NULL) 127 - return 0; 128 - 129 - return (pce_vmnet_write(dev->vmnet, buf, len) == 0 ? len : 0); 130 - #else 131 - if (dev->tap_fd < 0) { 132 - return 0; 133 - } 134 - 135 - return write (dev->tap_fd, buf, len); 136 - #endif 137 - }