patch-2.0.15 linux/drivers/net/ibmtr.c

Next file: linux/drivers/net/ibmtr.h
Previous file: linux/drivers/isdn/icn/icn.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.0.14/linux/drivers/net/ibmtr.c linux/drivers/net/ibmtr.c
@@ -50,6 +50,11 @@
 	- detecting PCMCIA Card Removal in interrupt handler.  if
 	  ISRP is FF, then a PCMCIA card has been removed
 
+   Changes by Paul Norton (pnorton@cts.com) :
+ 	- restructured the READ.LOG logic to prevent the transmit SRB
+	  from being rudely overwritten before the transmit cycle is
+	  complete. (August 15 1996)
+
    Warnings !!!!!!!!!!!!!!
       This driver is only partially sanitized for support of multiple
       adapters.  It will almost definitely fail if more than one
@@ -168,6 +173,7 @@
 static int tok_close(struct device *dev);
 static int tok_send_packet(struct sk_buff *skb, struct device *dev);
 static struct enet_statistics * tok_get_stats(struct device *dev);
+void tr_readlog(struct device *dev);
 
 static struct timer_list tr_timer={NULL,NULL,0,0L,tok_open_adapter};
 
@@ -331,6 +337,7 @@
 	memset(ti, 0, sizeof(struct tok_info));
 
 	ti->mmio= t_mmio;
+	ti->readlog_pending = 0;
 
 	dev->priv = ti;     /* this seems like the logical use of the
                          field ... let's try some empirical tests
@@ -730,6 +737,7 @@
 							      ti->current_skb=NULL;
 						      }
 						      dev->tbusy=0;
+						      if (ti->readlog_pending) tr_readlog(dev);
 					      }
 				      }
 				      break;
@@ -746,6 +754,7 @@
 							      ti->current_skb=NULL;
 						      }
 						      dev->tbusy=0;
+						      if (ti->readlog_pending) tr_readlog(dev);
 					      }
 				      }
 				      break;
@@ -761,7 +770,7 @@
 					      ti->current_skb=NULL;
 					      
 					      open_ret_code = readb(ti->init_srb +offsetof(struct srb_open_response, ret_code));
-					      open_error_code = readw(ti->init_srb +offsetof(struct srb_open_response, error_code));
+					      open_error_code = ntohs(readw(ti->init_srb +offsetof(struct srb_open_response, error_code)));
 
 					      if (open_ret_code==7) {
 						      
@@ -774,7 +783,7 @@
 							      DPRINTK("retrying open to adjust to ring speed\n");
 						      else if ((open_error_code==0x2d) && ti->auto_ringspeedsave)
 							      DPRINTK("No signal detected for Auto Speed Detection\n");
-						      else DPRINTK("Unrecoverable error: error code = %02X\n", 
+						      else DPRINTK("Unrecoverable error: error code = %04x\n", 
 								   open_error_code);
 						      
 					      } else if (!open_ret_code) {
@@ -887,10 +896,6 @@
 				      case REC_DATA:
 				      case XMIT_UI_FRAME:
 				      case XMIT_DIR_FRAME:
-					if (readb(ti->asb+2)!=0xff) /* checks ret_code */
-						DPRINTK("ASB error %02X in cmd %02X\n", 
-							(int)readb(ti->asb+2), 
-									(int)readb(ti->asb));
 					break;
 					
 				      default:
@@ -899,6 +904,9 @@
 					
 				} /* ASB command check */
 				
+				if (readb(ti->asb+2)!=0xff) /* checks ret_code */
+				    DPRINTK("ASB error %02X in cmd %02X\n", 
+					    (int)readb(ti->asb+2),(int)readb(ti->asb));
 				writeb(~ASB_FREE_INT, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_ODD);
 				
 			} /* ASB response */
@@ -938,14 +946,10 @@
 						      DPRINTK("New ring status: %02X\n", ring_status);
 					      
 					      if (ring_status & LOG_OVERFLOW) {
-						      
-						      writeb(DIR_READ_LOG, ti->srb);
-						      writeb(INT_ENABLE, 
-							     ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
-						      writeb(CMD_IN_SRB, 
-							     ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
-						      dev->tbusy=1; /* really srb busy... */
-						      
+						      if (dev->tbusy)
+                                                              ti->readlog_pending = 1;
+						      else
+                                                              tr_readlog(dev);
 					      }
 				      }
 				      break;
@@ -1269,6 +1273,7 @@
 	dev_kfree_skb(ti->current_skb,FREE_WRITE);
 	ti->current_skb=NULL;
 	mark_bh(NET_BH);
+	if (ti->readlog_pending) tr_readlog(dev);
 }
 
 static void tr_rx(struct device *dev) 
@@ -1468,7 +1473,18 @@
 	}
 	
 	return 0;
-}	
+}
+
+void tr_readlog(struct device *dev) {
+	 struct tok_info *ti;
+	 ti=(struct tok_info *) dev->priv;
+
+	 ti->readlog_pending = 0;
+	 writeb(DIR_READ_LOG, ti->srb);
+	 writeb(INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_SET + ISRP_EVEN);
+	 writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD);
+	 dev->tbusy=1; /* really srb busy... */
+}
 
 /* tok_get_stats():  Basically a scaffold routine which will return
    the address of the tr_statistics structure associated with
@@ -1493,16 +1509,21 @@
 	0, 0, 0, NULL, tok_probe };
 
 static int io = 0xa20;
+static char *device = NULL;
 
 int init_module(void)
 {
+	if (device)
+		strcpy(dev_ibmtr.name,device);
+	else if (!dev_ibmtr.name[0]) strcpy(dev_ibmtr.name,"tr0");
+
 	if (io == 0) 
 		printk("ibmtr: You should not use auto-probing with insmod!\n");
 	dev_ibmtr.base_addr = io;
 	dev_ibmtr.irq       = 0;
 	
 	if (register_netdev(&dev_ibmtr) != 0) {
-		printk("ibmtr: register_netdev() returned non-zero.\n");
+		printk("ibmtr: No adapters were found.\n");
 		return -EIO;
 	}
 	return 0;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov