Commit a747324c authored by Adam Belay's avatar Adam Belay

[ISAPNP] Fix Device Detection Issue

Some isapnp devices were not getting detected as a result of a bug in the isapnp
driver.  It was not following the specifications and calculating a checksum when
it was not reliable.  This problem was originally discovered by Paul L. Rogers
<rogerspl@datasync.com>.  He made an initial patch.  This release has some small
modifications, including a check to see if we run out of CSNs.
parent 7be9251f
...@@ -99,6 +99,7 @@ MODULE_LICENSE("GPL"); ...@@ -99,6 +99,7 @@ MODULE_LICENSE("GPL");
static unsigned char isapnp_checksum_value; static unsigned char isapnp_checksum_value;
static DECLARE_MUTEX(isapnp_cfg_mutex); static DECLARE_MUTEX(isapnp_cfg_mutex);
static int isapnp_detected; static int isapnp_detected;
static int isapnp_csn_count;
/* some prototypes */ /* some prototypes */
...@@ -371,11 +372,14 @@ static int __init isapnp_isolate(void) ...@@ -371,11 +372,14 @@ static int __init isapnp_isolate(void)
break; break;
} }
__next: __next:
if (csn == 255)
break;
checksum = 0x6a; checksum = 0x6a;
chksum = 0x00; chksum = 0x00;
bit = 0x00; bit = 0x00;
} }
isapnp_wait(); isapnp_wait();
isapnp_csn_count = csn;
return csn; return csn;
} }
...@@ -880,7 +884,7 @@ static int __init isapnp_build_device_list(void) ...@@ -880,7 +884,7 @@ static int __init isapnp_build_device_list(void)
isapnp_wait(); isapnp_wait();
isapnp_key(); isapnp_key();
for (csn = 1; csn <= 10; csn++) { for (csn = 1; csn <= isapnp_csn_count; csn++) {
isapnp_wake(csn); isapnp_wake(csn);
isapnp_peek(header, 9); isapnp_peek(header, 9);
checksum = isapnp_checksum(header); checksum = isapnp_checksum(header);
...@@ -890,12 +894,6 @@ static int __init isapnp_build_device_list(void) ...@@ -890,12 +894,6 @@ static int __init isapnp_build_device_list(void)
header[4], header[5], header[6], header[7], header[8]); header[4], header[5], header[6], header[7], header[8]);
printk(KERN_DEBUG "checksum = 0x%x\n", checksum); printk(KERN_DEBUG "checksum = 0x%x\n", checksum);
#endif #endif
/* Don't be strict on the checksum, here !
e.g. 'SCM SwapBox Plug and Play' has header[8]==0 (should be: b7)*/
if (header[8] == 0)
;
else if (checksum == 0x00 || checksum != header[8]) /* not valid CSN */
continue;
if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL) if ((card = isapnp_alloc(sizeof(struct pnp_card))) == NULL)
continue; continue;
...@@ -932,7 +930,7 @@ int isapnp_present(void) ...@@ -932,7 +930,7 @@ int isapnp_present(void)
int isapnp_cfg_begin(int csn, int logdev) int isapnp_cfg_begin(int csn, int logdev)
{ {
if (csn < 1 || csn > 10 || logdev > 10) if (csn < 1 || csn > isapnp_csn_count || logdev > 10)
return -EINVAL; return -EINVAL;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
down(&isapnp_cfg_mutex); down(&isapnp_cfg_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment