@@ 111,8 111,11 @@ configASIC(Ether* ether, int port, int xcvr)
static int
reset(Ether* ether)
{
- int slot;
+ int i, slot;
int port;
+ enum { WantAny, Want10BT, Want10B2 };
+ int want;
+ char *p;
if(ether->irq == 0)
ether->irq = 10;
@@ 120,31 123,56 @@ reset(Ether* ether)
ether->port = 0x240;
port = ether->port;
- if((slot = pcmspecial(ether->type, ether)) < 0)
+ if(ioalloc(port, 0x10, 0, "3C589") < 0)
return -1;
- /* try configuring as a 10BaseT */
- if(configASIC(ether, port, xcvr10BaseT) < 0){
- pcmspecialclose(slot);
+ if((slot = pcmspecial(ether->type, ether)) < 0){
+ iofree(port);
return -1;
}
- delay(100);
- COMMAND(port, SelectRegisterWindow, Wdiagnostic);
- if(ins(port+MediaStatus) & linkBeatDetect){
- COMMAND(port, SelectRegisterWindow, Wop);
- print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
- return 0;
+
+ /*
+ * Allow user to specify desired media in plan9.ini
+ */
+ want = WantAny;
+ for(i = 0; i < ether->nopt; i++){
+ if(cistrncmp(ether->opt[i], "media=", 6) != 0)
+ continue;
+ p = ether->opt[i]+6;
+ if(cistrcmp(p, "10base2") == 0)
+ want = Want10B2;
+ else if(cistrcmp(p, "10baseT") == 0)
+ want = Want10BT;
+ }
+
+ /* try configuring as a 10BaseT */
+ if(want==WantAny || want==Want10BT){
+ if(configASIC(ether, port, xcvr10BaseT) < 0){
+ pcmspecialclose(slot);
+ iofree(port);
+ return -1;
+ }
+ delay(100);
+ COMMAND(port, SelectRegisterWindow, Wdiagnostic);
+ if((ins(port+MediaStatus)&linkBeatDetect) || want==Want10BT){
+ COMMAND(port, SelectRegisterWindow, Wop);
+ print("#l%d: xcvr10BaseT %s\n", ether->ctlrno, ether->type);
+ return 0;
+ }
}
/* try configuring as a 10base2 */
- COMMAND(port, GlobalReset, 0);
- if(configASIC(ether, port, xcvr10Base2) < 0){
- pcmspecialclose(slot);
- return -1;
+ if(want==WantAny || want==Want10B2){
+ COMMAND(port, GlobalReset, 0);
+ if(configASIC(ether, port, xcvr10Base2) < 0){
+ pcmspecialclose(slot);
+ iofree(port);
+ return -1;
+ }
+ print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);
+ return 0;
}
- print("#l%d: xcvr10Base2 %s\n", ether->ctlrno, ether->type);
-
- return 0;
+ return -1; /* not reached */
}
void
@@ 43,6 43,10 @@ void gotopc(ulong);
void icflush(void*, ulong);
void idle(void);
#define idlehands() /* nothing to do in the runproc */
+void iofree(int);
+void ioinit(void);
+int iounused(int, int);
+int ioalloc(int, int, int, char*);
int inb(int);
void insb(int, void*, int);
ushort ins(int);
@@ 435,3 435,41 @@ cistrcmp(char *a, char *b)
return 0;
}
+int
+cistrncmp(char *a, char *b, int n)
+{
+ unsigned ac, bc;
+
+ while(n > 0){
+ ac = *a++;
+ bc = *b++;
+ n--;
+
+ if(ac >= 'A' && ac <= 'Z')
+ ac = 'a' + (ac - 'A');
+ if(bc >= 'A' && bc <= 'Z')
+ bc = 'a' + (bc - 'A');
+
+ ac -= bc;
+ if(ac)
+ return ac;
+ if(bc == 0)
+ break;
+ }
+
+ return 0;
+}
+
+/* dummy - not used */
+
+void
+iofree(int)
+{
+}
+
+int
+ioalloc(int, int, int, char*)
+{
+ return 1;
+}
+