树莓派远程连接不上的一些日志。求大拿分析。
突然出现这个错误,这是重启后在messages中查看到的。之前的日志没有异常,
出现一下信息后的pi处于无法连接状态。
有没有人能分析下原因嗯。
Nov 22 00:26:47 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:12:16 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:56:39 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:56:44 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000114
Nov 22 01:56:49 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:56:54 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000118
Nov 22 01:56:59 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:04 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000114
Nov 22 01:57:09 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:14 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000118
Nov 22 01:57:21 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:26 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000114
Nov 22 01:57:31 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:36 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000118
Nov 22 01:57:41 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:46 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000114
Nov 22 01:57:51 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000114
Nov 22 01:57:56 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x00000118
Nov 22 01:58:01 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014
Nov 22 01:58:01 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = -110
Nov 22 01:58:07 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014
Nov 22 01:58:07 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = -110
Nov 22 01:58:13 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014
Nov 22 01:58:13 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = -110
Nov 22 01:58:19 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014
Nov 22 01:58:19 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = -110
Nov 22 01:58:25 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014
Nov 22 01:58:25 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = -110
Nov 22 01:58:31 raspberrypi kernel: smsc95xx 1-1.1:1.0: eth0: Failed to write register index 0x00000014 找到个相关信息但是我的设备不是这个设备。
Dell
Dell U2410 Monitor Built-in 4 Port Hub - Shows up as a pair with 0424:2514 and 0424:2640. Standard Microsystems Corp. USB 2.0 Hub. When connecting some devices it kills the Ethernet with "smsc95xx 1-1.1:1.0: eth0: Failed to read register index 0x0000011X" errors. It did work for a keyboard and webcam. Bluetooth that works connected directly to the Pi triggers the error. 自己挖坑自己埋。~~~
找到网卡的源码,然后发现这个网卡是用的usb总线的。
static int smsc95xx_read_reg(struct usbnet *dev, u32 index, u32 *data)
{
u32 *buf = kmalloc(4, GFP_KERNEL);
int ret;
BUG_ON(!dev);
if (!buf)
return -ENOMEM;
ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
USB_VENDOR_REQUEST_READ_REGISTER,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
00, index, buf, 4, USB_CTRL_GET_TIMEOUT);
if (unlikely(ret < 0))
netdev_warn(dev->net, "Failed to read register index 0x%08x\n", index);
le32_to_cpus(buf);
*data = *buf;
kfree(buf);
return ret;
} 编辑不了帖子了,只好回复了。
static int smsc95xx_reset(struct usbnet *dev)
{
struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data);
struct net_device *netdev = dev->net;
u32 read_buf, write_buf, burst_cap;
int ret = 0, timeout;
netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
write_buf = HW_CFG_LRST_;
ret = smsc95xx_write_reg(dev, HW_CFG, write_buf);
if (ret < 0) {
netdev_warn(dev->net, "Failed to write HW_CFG_LRST_ bit in HW_CFG register, ret = %d\n", ret); //问题就处在这个地方
return ret;
略~~
将request, requesttype, value, index, size加工成usb_ctrlrequest,然后调用usb_internal_control_msg()
dev 参数dev指向目标设备的usb_device数据结构
pipe pipe是个32位无符号整数,其最高两位表示传输的类型(实时/中断/控制/批量),其余各位包括对方的端口号以及设备号,以及设备是否为全速(或者低度)。
requesttype requesttype其最高位表示传输的方向,最低5位则表明传输终极对象的类别(设备/接口/端口/其他)
index, request, value index则指明具体的单元,这就是终极的操作对象。针对这个操作对象,request说明了需要进行的具体操作,而value则是参数
data, size 如果有更多的数据需要传递(读/写),则通过缓冲区data进行,其大小为size。 这些都是从用户空间传下来的参数,而传输的目的正是要把这些信息发送给目标设备
timeout 参数timeout表示愿意睡眠等待传输完成的时间
------------------------------------------------------
int usb_control_msg(
struct usb_device *dev, unsigned int pipe,
__u8 -request, __u8 requesttype, __u16 value,
__u16 index, void *data, __u16 size,
int timeout)
{
struct usb_ctrlrequest *dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO);
int ret;
if (!dr)
return -ENOMEM;
dr->bRequestType= requesttype;
dr->bRequest = request;
dr->wValue = cpu_to_le16p(&value);
dr->wIndex = cpu_to_le16p(&index);
dr->wLength = cpu_to_le16p(&size);
ret = usb_internal_control_msg(dev, pipe, dr, data, size, timeout);
kfree(dr);
return ret;
}static int usb_internal_control_msg(
struct usb_device *usb_dev,
unsigned int pipe,
struct usb_ctrlrequest *cmd,
void *data, int len, int timeout)
{
struct urb *urb;
int retv;
int length;
urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;
使用参数填充urb,并给urb安插一个回调函数usb_api_blocking_completion(),底层在处理完urb后将会调用该回调函数
|------------------------------------------------------------------------|
| usb_fill_control_urb( urb, -usb_dev, pipe, |
| (unsigned char *) -cmd, |
| data, len, usb_api_blocking_completion,|
| NULL); |
|------------------------------------------------------------------------|
设置好urb以后,通过usb_start_wait_urb()“递交”这个urb数据结构,并等待交互的完成
|-------------------------------------------------------|
| retv = usb_start_wait_urb(urb, timeout, &length); |
|-------------------------------------------------------|
if (retv < 0)
return retv;
else
return length;
}
注:
1. 根Hub最终将通过对urb进行排队
2. 根Hub将通过如下路径回调函数usb_api_blocking_completion()
usb_start_wait_urb()
--> usb_submit_urb()
--> usb_hcd_submit_urb()
--> rh_urb_enqueue()
--> rh_call_control()
--> usb_hcd_giveback_urb()
--> usb_api_blocking_completion() static int usb_start_wait_urb( struct urb *urb,
int timeout,
int *actual_length)
{
struct completion done;
unsigned long expire;
int status;
init_completion(&done);
urb->context = &done;
urb->actual_length = 0;
将加工好的urb递交给主控制器排队 //问题在这。:@
|---------------------------------------------|
| status = usb_submit_urb(urb, GFP_NOIO); |
|---------------------------------------------|
if (unlikely(status))
goto out;
expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT;
if (!wait_for_completion_timeout(&done, expire)) {
dev_dbg(&urb->dev->dev,
"%s timed out on ep%d%s len=%d/%d\n",
current->comm,
usb_pipeendpoint(urb->pipe),
usb_pipein(urb->pipe) ? "in" : "out",
urb->actual_length,
urb->transfer_buffer_length);
通过urb获取有效数据后,urb的使命就完成了
|------------------------------|
| usb_kill_urb(urb); |
|------------------------------|
status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status;
} else
status = urb->status;
out:
if (actual_length)
*actual_length = urb->actual_length;
usb_free_urb(urb);
return status;
} 最后到了最关键的了
错误代码:
-ENOMEM 内存不足
-ENODEV 没有设备可用
-EPIPE 端点停止
-EAGAIN 排队等候同步传输的太多
-EFBIG 请求ISO frame的太多
-EINVAL 无效的中断间隔
函数usb_submit_urb递交URB后,urb->status为-EINPROGRESS.
--------------------------------------------------------
int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
{
int pipe, temp, max;
struct usb_device *dev;
int is_out;
if (!urb || urb->hcpriv || !urb->complete)
return -EINVAL;
if (!(dev = urb->dev) ||
(dev->state < USB_STATE_DEFAULT) ||
(!dev->bus) || (dev->devnum <= 0))
return -ENODEV;
if (dev->bus->controller->power.power_state.event != PM_EVENT_ON
|| dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
urb->status = -EINPROGRESS;
urb->actual_length = 0;
pipe = urb->pipe;
temp = usb_pipetype(pipe);
is_out = usb_pipeout(pipe);
if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED)
return -ENODEV;
//获取usb设备dev所能传输的数据包的最大值(单位是字节)
max = usb_maxpacket(dev, pipe, is_out);
if (max <= 0) {
dev_dbg(&dev->dev,
"bogus endpoint ep%d%s in %s (bad maxpacket %d)\n",
usb_pipeendpoint(pipe), is_out ? "out" : "in",
__FUNCTION__, max);
return -EMSGSIZE;
}
处理“负责实时传输的urb”
|---------------------------------------------------------|
| if (temp == PIPE_ISOCHRONOUS) { |
| int n, len; |
| if (dev->speed == USB_SPEED_HIGH) { |
| int mult = 1 + ((max >> 11) & 0x03); |
| max &= 0x07ff; |
| max *= mult; |
| } |
| if (urb->number_of_packets <= 0) |
| return -EINVAL; |
| for (n = 0; n < urb->number_of_packets; n++) { |
| len = urb->iso_frame_desc.length; |
| if (len < 0 || len > max) |
| return -EMSGSIZE; |
| urb->iso_frame_desc.status = -EXDEV; |
| urb->iso_frame_desc.actual_length = 0; |
| } |
| } |
|---------------------------------------------------------|
if (urb->transfer_buffer_length < 0)
return -EMSGSIZE;
--------------------------------------------------------
#ifdef DEBUG
{
unsigned int orig_flags = urb->transfer_flags;
unsigned int allowed;
allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
URB_NO_INTERRUPT);
switch (temp) {
case PIPE_BULK:
if (is_out)
allowed |= URB_ZERO_PACKET;
case PIPE_CONTROL:
allowed |= URB_NO_FSBR;
default:
if (!is_out)
allowed |= URB_SHORT_NOT_OK;
break;
case PIPE_ISOCHRONOUS:
allowed |= URB_ISO_ASAP;
break;
}
urb->transfer_flags &= allowed;
if (urb->transfer_flags != orig_flags) {
err("BOGUS urb flags, %x --> %x",
orig_flags, urb->transfer_flags);
return -EINVAL;
}
}
#endif
--------------------------------------------------------
设置urb的interval域
********************************************************
switch (temp) {
case PIPE_ISOCHRONOUS:
case PIPE_INTERRUPT:
if (urb->interval <= 0)
return -EINVAL;
switch (dev->speed) {
case USB_SPEED_HIGH:
if (urb->interval > (1024 * 8))
urb->interval = 1024 * 8;
temp = 1024 * 8;
break;
case USB_SPEED_FULL:
case USB_SPEED_LOW:
if (temp == PIPE_INTERRUPT) {
if (urb->interval > 255)
return -EINVAL;
temp = 128;
} else {
if (urb->interval > 1024)
urb->interval = 1024;
temp = 1024;
}
break;
default:
return -EINVAL;
}
while (temp > urb->interval)
temp >>= 1;
urb->interval = temp;
}
********************************************************
return usb_hcd_submit_urb(urb, mem_flags);
}
一头雾水! 楼主是用RJ45口还是有插了一个无线网卡? google了一下,你看看是不是这个供电干扰问题,您把给raspi供电 和 路由器供电分开试试,或者换个适配器。
原文参考:http://www.raspberrypi.org/phpBB3/viewtopic.php?t=11971&p=129570 本帖最后由 Damn_intuition 于 2012-11-22 21:13 编辑
gaoshine 发表于 2012-11-22 18:00 static/image/common/back.gif
google了一下,你看看是不是这个供电干扰问题,您把给raspi供电 和 路由器供电分开试试,或者换个适配器。
...
谢谢,我看了下电路和源码,根据猜测是因为usb设备出问题导致的。
因为现在我找不到0x000000那个错误码(手里没有完整的源码),错误码的值定义还不明确。
貌似是因为设备的一些电路因为插排产生电子干扰。产生了一些回路什么的。。。
页:
[1]