diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 18:08:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 18:08:34 -0400 |
commit | eaa8568901b3164197ce727c4c9b4067383e526c (patch) | |
tree | 6dc48f016cfff6e1e5ce9278be819e1b651027b0 /drivers | |
parent | 6c763eb9ead86c612492b59287b36c0dcf7d09b1 (diff) | |
parent | c6976a4eb3c9ead165de950899b45db0840b8e30 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/w1-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/w1-2.6:
[PATCH] w1: warning fix
[PATCH] w1: clean up W1_CON dependency.
[PATCH] drivers/w1/w1.c: fix a compile error
[PATCH] W1: fix dependencies of W1_SLAVE_DS2433_CRC
[PATCH] W1: possible cleanups
[PATCH] W1: cleanups
[PATCH] w1 exports
[PATCH] w1: Use mutexes instead of semaphores.
[PATCH] w1: Make w1 connector notifications depend on connector.
[PATCH] w1: netlink: Mark netlink group 1 as unused.
[PATCH] w1: Move w1-connector definitions into linux/include/connector.h
[PATCH] w1: Userspace communication protocol over connector.
[PATCH] w1: Replace dscore and ds_w1_bridge with ds2490 driver.
[PATCH] w1: Added default generic read/write operations.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/w1/Kconfig | 14 | ||||
-rw-r--r-- | drivers/w1/Makefile | 4 | ||||
-rw-r--r-- | drivers/w1/masters/Kconfig | 27 | ||||
-rw-r--r-- | drivers/w1/masters/Makefile | 7 | ||||
-rw-r--r-- | drivers/w1/masters/ds2482.c | 24 | ||||
-rw-r--r-- | drivers/w1/masters/ds2490.c (renamed from drivers/w1/masters/dscore.c) | 434 | ||||
-rw-r--r-- | drivers/w1/masters/ds_w1_bridge.c | 174 | ||||
-rw-r--r-- | drivers/w1/masters/dscore.h | 166 | ||||
-rw-r--r-- | drivers/w1/slaves/Kconfig | 2 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2433.c | 21 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_smem.c | 1 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_therm.c | 13 | ||||
-rw-r--r-- | drivers/w1/w1.c | 263 | ||||
-rw-r--r-- | drivers/w1/w1.h | 41 | ||||
-rw-r--r-- | drivers/w1/w1_family.c | 18 | ||||
-rw-r--r-- | drivers/w1/w1_family.h | 3 | ||||
-rw-r--r-- | drivers/w1/w1_int.c | 16 | ||||
-rw-r--r-- | drivers/w1/w1_io.c | 31 | ||||
-rw-r--r-- | drivers/w1/w1_io.h | 3 | ||||
-rw-r--r-- | drivers/w1/w1_netlink.c | 219 | ||||
-rw-r--r-- | drivers/w1/w1_netlink.h | 35 |
21 files changed, 773 insertions, 743 deletions
diff --git a/drivers/w1/Kconfig b/drivers/w1/Kconfig index 5e61ed59a41e..f2d9a08e89ae 100644 --- a/drivers/w1/Kconfig +++ b/drivers/w1/Kconfig | |||
@@ -3,7 +3,7 @@ menu "Dallas's 1-wire bus" | |||
3 | config W1 | 3 | config W1 |
4 | tristate "Dallas's 1-wire support" | 4 | tristate "Dallas's 1-wire support" |
5 | ---help--- | 5 | ---help--- |
6 | Dallas's 1-wire bus is useful to connect slow 1-pin devices | 6 | Dallas' 1-wire bus is useful to connect slow 1-pin devices |
7 | such as iButtons and thermal sensors. | 7 | such as iButtons and thermal sensors. |
8 | 8 | ||
9 | If you want W1 support, you should say Y here. | 9 | If you want W1 support, you should say Y here. |
@@ -11,6 +11,18 @@ config W1 | |||
11 | This W1 support can also be built as a module. If so, the module | 11 | This W1 support can also be built as a module. If so, the module |
12 | will be called wire.ko. | 12 | will be called wire.ko. |
13 | 13 | ||
14 | config W1_CON | ||
15 | depends on CONNECTOR && W1 | ||
16 | bool "Userspace communication over connector" | ||
17 | default y | ||
18 | --- help --- | ||
19 | This allows to communicate with userspace using connector [Documentation/connector]. | ||
20 | There are three types of messages between w1 core and userspace: | ||
21 | 1. Events. They are generated each time new master or slave device found | ||
22 | either due to automatic or requested search. | ||
23 | 2. Userspace commands. Includes read/write and search/alarm search comamnds. | ||
24 | 3. Replies to userspace commands. | ||
25 | |||
14 | source drivers/w1/masters/Kconfig | 26 | source drivers/w1/masters/Kconfig |
15 | source drivers/w1/slaves/Kconfig | 27 | source drivers/w1/slaves/Kconfig |
16 | 28 | ||
diff --git a/drivers/w1/Makefile b/drivers/w1/Makefile index 0c2aa22d8c04..93845a2c7c21 100644 --- a/drivers/w1/Makefile +++ b/drivers/w1/Makefile | |||
@@ -2,10 +2,6 @@ | |||
2 | # Makefile for the Dallas's 1-wire bus. | 2 | # Makefile for the Dallas's 1-wire bus. |
3 | # | 3 | # |
4 | 4 | ||
5 | ifneq ($(CONFIG_NET), y) | ||
6 | EXTRA_CFLAGS += -DNETLINK_DISABLED | ||
7 | endif | ||
8 | |||
9 | ifeq ($(CONFIG_W1_DS2433_CRC), y) | 5 | ifeq ($(CONFIG_W1_DS2433_CRC), y) |
10 | EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC | 6 | EXTRA_CFLAGS += -DCONFIG_W1_F23_CRC |
11 | endif | 7 | endif |
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index c6bad4dbdc64..2fb425536eae 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig | |||
@@ -15,24 +15,15 @@ config W1_MASTER_MATROX | |||
15 | This support is also available as a module. If so, the module | 15 | This support is also available as a module. If so, the module |
16 | will be called matrox_w1.ko. | 16 | will be called matrox_w1.ko. |
17 | 17 | ||
18 | config W1_MASTER_DS9490 | 18 | config W1_MASTER_DS2490 |
19 | tristate "DS9490R transport layer driver" | 19 | tristate "DS2490 USB <-> W1 transport layer for 1-wire" |
20 | depends on W1 && USB | 20 | depends on W1 && USB |
21 | help | 21 | help |
22 | Say Y here if you want to have a driver for DS9490R UWB <-> W1 bridge. | 22 | Say Y here if you want to have a driver for DS2490 based USB <-> W1 bridges, |
23 | 23 | for example DS9490*. | |
24 | This support is also available as a module. If so, the module | 24 | |
25 | will be called ds9490r.ko. | 25 | This support is also available as a module. If so, the module |
26 | 26 | will be called ds2490.ko. | |
27 | config W1_MASTER_DS9490_BRIDGE | ||
28 | tristate "DS9490R USB <-> W1 transport layer for 1-wire" | ||
29 | depends on W1_MASTER_DS9490 | ||
30 | help | ||
31 | Say Y here if you want to communicate with your 1-wire devices | ||
32 | using DS9490R USB bridge. | ||
33 | |||
34 | This support is also available as a module. If so, the module | ||
35 | will be called ds_w1_bridge.ko. | ||
36 | 27 | ||
37 | config W1_MASTER_DS2482 | 28 | config W1_MASTER_DS2482 |
38 | tristate "Maxim DS2482 I2C to 1-Wire bridge" | 29 | tristate "Maxim DS2482 I2C to 1-Wire bridge" |
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile index 1f3c8b983dc1..4cee256a8134 100644 --- a/drivers/w1/masters/Makefile +++ b/drivers/w1/masters/Makefile | |||
@@ -3,11 +3,6 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o | 5 | obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o |
6 | 6 | obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o | |
7 | obj-$(CONFIG_W1_MASTER_DS9490) += ds9490r.o | ||
8 | ds9490r-objs := dscore.o | ||
9 | |||
10 | obj-$(CONFIG_W1_MASTER_DS9490_BRIDGE) += ds_w1_bridge.o | ||
11 | |||
12 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o | 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o |
13 | 8 | ||
diff --git a/drivers/w1/masters/ds2482.c b/drivers/w1/masters/ds2482.c index d1cacd23576b..af492cc48db2 100644 --- a/drivers/w1/masters/ds2482.c +++ b/drivers/w1/masters/ds2482.c | |||
@@ -125,7 +125,7 @@ struct ds2482_w1_chan { | |||
125 | 125 | ||
126 | struct ds2482_data { | 126 | struct ds2482_data { |
127 | struct i2c_client client; | 127 | struct i2c_client client; |
128 | struct semaphore access_lock; | 128 | struct mutex access_lock; |
129 | 129 | ||
130 | /* 1-wire interface(s) */ | 130 | /* 1-wire interface(s) */ |
131 | int w1_count; /* 1 or 8 */ | 131 | int w1_count; /* 1 or 8 */ |
@@ -265,7 +265,7 @@ static u8 ds2482_w1_touch_bit(void *data, u8 bit) | |||
265 | struct ds2482_data *pdev = pchan->pdev; | 265 | struct ds2482_data *pdev = pchan->pdev; |
266 | int status = -1; | 266 | int status = -1; |
267 | 267 | ||
268 | down(&pdev->access_lock); | 268 | mutex_lock(&pdev->access_lock); |
269 | 269 | ||
270 | /* Select the channel */ | 270 | /* Select the channel */ |
271 | ds2482_wait_1wire_idle(pdev); | 271 | ds2482_wait_1wire_idle(pdev); |
@@ -277,7 +277,7 @@ static u8 ds2482_w1_touch_bit(void *data, u8 bit) | |||
277 | bit ? 0xFF : 0)) | 277 | bit ? 0xFF : 0)) |
278 | status = ds2482_wait_1wire_idle(pdev); | 278 | status = ds2482_wait_1wire_idle(pdev); |
279 | 279 | ||
280 | up(&pdev->access_lock); | 280 | mutex_unlock(&pdev->access_lock); |
281 | 281 | ||
282 | return (status & DS2482_REG_STS_SBR) ? 1 : 0; | 282 | return (status & DS2482_REG_STS_SBR) ? 1 : 0; |
283 | } | 283 | } |
@@ -297,7 +297,7 @@ static u8 ds2482_w1_triplet(void *data, u8 dbit) | |||
297 | struct ds2482_data *pdev = pchan->pdev; | 297 | struct ds2482_data *pdev = pchan->pdev; |
298 | int status = (3 << 5); | 298 | int status = (3 << 5); |
299 | 299 | ||
300 | down(&pdev->access_lock); | 300 | mutex_lock(&pdev->access_lock); |
301 | 301 | ||
302 | /* Select the channel */ | 302 | /* Select the channel */ |
303 | ds2482_wait_1wire_idle(pdev); | 303 | ds2482_wait_1wire_idle(pdev); |
@@ -309,7 +309,7 @@ static u8 ds2482_w1_triplet(void *data, u8 dbit) | |||
309 | dbit ? 0xFF : 0)) | 309 | dbit ? 0xFF : 0)) |
310 | status = ds2482_wait_1wire_idle(pdev); | 310 | status = ds2482_wait_1wire_idle(pdev); |
311 | 311 | ||
312 | up(&pdev->access_lock); | 312 | mutex_unlock(&pdev->access_lock); |
313 | 313 | ||
314 | /* Decode the status */ | 314 | /* Decode the status */ |
315 | return (status >> 5); | 315 | return (status >> 5); |
@@ -326,7 +326,7 @@ static void ds2482_w1_write_byte(void *data, u8 byte) | |||
326 | struct ds2482_w1_chan *pchan = data; | 326 | struct ds2482_w1_chan *pchan = data; |
327 | struct ds2482_data *pdev = pchan->pdev; | 327 | struct ds2482_data *pdev = pchan->pdev; |
328 | 328 | ||
329 | down(&pdev->access_lock); | 329 | mutex_lock(&pdev->access_lock); |
330 | 330 | ||
331 | /* Select the channel */ | 331 | /* Select the channel */ |
332 | ds2482_wait_1wire_idle(pdev); | 332 | ds2482_wait_1wire_idle(pdev); |
@@ -336,7 +336,7 @@ static void ds2482_w1_write_byte(void *data, u8 byte) | |||
336 | /* Send the write byte command */ | 336 | /* Send the write byte command */ |
337 | ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte); | 337 | ds2482_send_cmd_data(pdev, DS2482_CMD_1WIRE_WRITE_BYTE, byte); |
338 | 338 | ||
339 | up(&pdev->access_lock); | 339 | mutex_unlock(&pdev->access_lock); |
340 | } | 340 | } |
341 | 341 | ||
342 | /** | 342 | /** |
@@ -351,7 +351,7 @@ static u8 ds2482_w1_read_byte(void *data) | |||
351 | struct ds2482_data *pdev = pchan->pdev; | 351 | struct ds2482_data *pdev = pchan->pdev; |
352 | int result; | 352 | int result; |
353 | 353 | ||
354 | down(&pdev->access_lock); | 354 | mutex_lock(&pdev->access_lock); |
355 | 355 | ||
356 | /* Select the channel */ | 356 | /* Select the channel */ |
357 | ds2482_wait_1wire_idle(pdev); | 357 | ds2482_wait_1wire_idle(pdev); |
@@ -370,7 +370,7 @@ static u8 ds2482_w1_read_byte(void *data) | |||
370 | /* Read the data byte */ | 370 | /* Read the data byte */ |
371 | result = i2c_smbus_read_byte(&pdev->client); | 371 | result = i2c_smbus_read_byte(&pdev->client); |
372 | 372 | ||
373 | up(&pdev->access_lock); | 373 | mutex_unlock(&pdev->access_lock); |
374 | 374 | ||
375 | return result; | 375 | return result; |
376 | } | 376 | } |
@@ -389,7 +389,7 @@ static u8 ds2482_w1_reset_bus(void *data) | |||
389 | int err; | 389 | int err; |
390 | u8 retval = 1; | 390 | u8 retval = 1; |
391 | 391 | ||
392 | down(&pdev->access_lock); | 392 | mutex_lock(&pdev->access_lock); |
393 | 393 | ||
394 | /* Select the channel */ | 394 | /* Select the channel */ |
395 | ds2482_wait_1wire_idle(pdev); | 395 | ds2482_wait_1wire_idle(pdev); |
@@ -409,7 +409,7 @@ static u8 ds2482_w1_reset_bus(void *data) | |||
409 | 0xF0); | 409 | 0xF0); |
410 | } | 410 | } |
411 | 411 | ||
412 | up(&pdev->access_lock); | 412 | mutex_unlock(&pdev->access_lock); |
413 | 413 | ||
414 | return retval; | 414 | return retval; |
415 | } | 415 | } |
@@ -482,7 +482,7 @@ static int ds2482_detect(struct i2c_adapter *adapter, int address, int kind) | |||
482 | snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00", | 482 | snprintf(new_client->name, sizeof(new_client->name), "ds2482-%d00", |
483 | data->w1_count); | 483 | data->w1_count); |
484 | 484 | ||
485 | init_MUTEX(&data->access_lock); | 485 | mutex_init(&data->access_lock); |
486 | 486 | ||
487 | /* Tell the I2C layer a new client has arrived */ | 487 | /* Tell the I2C layer a new client has arrived */ |
488 | if ((err = i2c_attach_client(new_client))) | 488 | if ((err = i2c_attach_client(new_client))) |
diff --git a/drivers/w1/masters/dscore.c b/drivers/w1/masters/ds2490.c index 2cf7776a7080..299e274d241a 100644 --- a/drivers/w1/masters/dscore.c +++ b/drivers/w1/masters/ds2490.c | |||
@@ -24,7 +24,136 @@ | |||
24 | #include <linux/mod_devicetable.h> | 24 | #include <linux/mod_devicetable.h> |
25 | #include <linux/usb.h> | 25 | #include <linux/usb.h> |
26 | 26 | ||
27 | #include "dscore.h" | 27 | #include "../w1_int.h" |
28 | #include "../w1.h" | ||
29 | |||
30 | /* COMMAND TYPE CODES */ | ||
31 | #define CONTROL_CMD 0x00 | ||
32 | #define COMM_CMD 0x01 | ||
33 | #define MODE_CMD 0x02 | ||
34 | |||
35 | /* CONTROL COMMAND CODES */ | ||
36 | #define CTL_RESET_DEVICE 0x0000 | ||
37 | #define CTL_START_EXE 0x0001 | ||
38 | #define CTL_RESUME_EXE 0x0002 | ||
39 | #define CTL_HALT_EXE_IDLE 0x0003 | ||
40 | #define CTL_HALT_EXE_DONE 0x0004 | ||
41 | #define CTL_FLUSH_COMM_CMDS 0x0007 | ||
42 | #define CTL_FLUSH_RCV_BUFFER 0x0008 | ||
43 | #define CTL_FLUSH_XMT_BUFFER 0x0009 | ||
44 | #define CTL_GET_COMM_CMDS 0x000A | ||
45 | |||
46 | /* MODE COMMAND CODES */ | ||
47 | #define MOD_PULSE_EN 0x0000 | ||
48 | #define MOD_SPEED_CHANGE_EN 0x0001 | ||
49 | #define MOD_1WIRE_SPEED 0x0002 | ||
50 | #define MOD_STRONG_PU_DURATION 0x0003 | ||
51 | #define MOD_PULLDOWN_SLEWRATE 0x0004 | ||
52 | #define MOD_PROG_PULSE_DURATION 0x0005 | ||
53 | #define MOD_WRITE1_LOWTIME 0x0006 | ||
54 | #define MOD_DSOW0_TREC 0x0007 | ||
55 | |||
56 | /* COMMUNICATION COMMAND CODES */ | ||
57 | #define COMM_ERROR_ESCAPE 0x0601 | ||
58 | #define COMM_SET_DURATION 0x0012 | ||
59 | #define COMM_BIT_IO 0x0020 | ||
60 | #define COMM_PULSE 0x0030 | ||
61 | #define COMM_1_WIRE_RESET 0x0042 | ||
62 | #define COMM_BYTE_IO 0x0052 | ||
63 | #define COMM_MATCH_ACCESS 0x0064 | ||
64 | #define COMM_BLOCK_IO 0x0074 | ||
65 | #define COMM_READ_STRAIGHT 0x0080 | ||
66 | #define COMM_DO_RELEASE 0x6092 | ||
67 | #define COMM_SET_PATH 0x00A2 | ||
68 | #define COMM_WRITE_SRAM_PAGE 0x00B2 | ||
69 | #define COMM_WRITE_EPROM 0x00C4 | ||
70 | #define COMM_READ_CRC_PROT_PAGE 0x00D4 | ||
71 | #define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 | ||
72 | #define COMM_SEARCH_ACCESS 0x00F4 | ||
73 | |||
74 | /* Communication command bits */ | ||
75 | #define COMM_TYPE 0x0008 | ||
76 | #define COMM_SE 0x0008 | ||
77 | #define COMM_D 0x0008 | ||
78 | #define COMM_Z 0x0008 | ||
79 | #define COMM_CH 0x0008 | ||
80 | #define COMM_SM 0x0008 | ||
81 | #define COMM_R 0x0008 | ||
82 | #define COMM_IM 0x0001 | ||
83 | |||
84 | #define COMM_PS 0x4000 | ||
85 | #define COMM_PST 0x4000 | ||
86 | #define COMM_CIB 0x4000 | ||
87 | #define COMM_RTS 0x4000 | ||
88 | #define COMM_DT 0x2000 | ||
89 | #define COMM_SPU 0x1000 | ||
90 | #define COMM_F 0x0800 | ||
91 | #define COMM_NTP 0x0400 | ||
92 | #define COMM_ICP 0x0200 | ||
93 | #define COMM_RST 0x0100 | ||
94 | |||
95 | #define PULSE_PROG 0x01 | ||
96 | #define PULSE_SPUE 0x02 | ||
97 | |||
98 | #define BRANCH_MAIN 0xCC | ||
99 | #define BRANCH_AUX 0x33 | ||
100 | |||
101 | /* | ||
102 | * Duration of the strong pull-up pulse in milliseconds. | ||
103 | */ | ||
104 | #define PULLUP_PULSE_DURATION 750 | ||
105 | |||
106 | /* Status flags */ | ||
107 | #define ST_SPUA 0x01 /* Strong Pull-up is active */ | ||
108 | #define ST_PRGA 0x02 /* 12V programming pulse is being generated */ | ||
109 | #define ST_12VP 0x04 /* external 12V programming voltage is present */ | ||
110 | #define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ | ||
111 | #define ST_HALT 0x10 /* DS2490 is currently halted */ | ||
112 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ | ||
113 | #define ST_EPOF 0x80 | ||
114 | |||
115 | #define SPEED_NORMAL 0x00 | ||
116 | #define SPEED_FLEXIBLE 0x01 | ||
117 | #define SPEED_OVERDRIVE 0x02 | ||
118 | |||
119 | #define NUM_EP 4 | ||
120 | #define EP_CONTROL 0 | ||
121 | #define EP_STATUS 1 | ||
122 | #define EP_DATA_OUT 2 | ||
123 | #define EP_DATA_IN 3 | ||
124 | |||
125 | struct ds_device | ||
126 | { | ||
127 | struct list_head ds_entry; | ||
128 | |||
129 | struct usb_device *udev; | ||
130 | struct usb_interface *intf; | ||
131 | |||
132 | int ep[NUM_EP]; | ||
133 | |||
134 | struct w1_bus_master master; | ||
135 | }; | ||
136 | |||
137 | struct ds_status | ||
138 | { | ||
139 | u8 enable; | ||
140 | u8 speed; | ||
141 | u8 pullup_dur; | ||
142 | u8 ppuls_dur; | ||
143 | u8 pulldown_slew; | ||
144 | u8 write1_time; | ||
145 | u8 write0_time; | ||
146 | u8 reserved0; | ||
147 | u8 status; | ||
148 | u8 command0; | ||
149 | u8 command1; | ||
150 | u8 command_buffer_status; | ||
151 | u8 data_out_buffer_status; | ||
152 | u8 data_in_buffer_status; | ||
153 | u8 reserved1; | ||
154 | u8 reserved2; | ||
155 | |||
156 | }; | ||
28 | 157 | ||
29 | static struct usb_device_id ds_id_table [] = { | 158 | static struct usb_device_id ds_id_table [] = { |
30 | { USB_DEVICE(0x04fa, 0x2490) }, | 159 | { USB_DEVICE(0x04fa, 0x2490) }, |
@@ -35,21 +164,12 @@ MODULE_DEVICE_TABLE(usb, ds_id_table); | |||
35 | static int ds_probe(struct usb_interface *, const struct usb_device_id *); | 164 | static int ds_probe(struct usb_interface *, const struct usb_device_id *); |
36 | static void ds_disconnect(struct usb_interface *); | 165 | static void ds_disconnect(struct usb_interface *); |
37 | 166 | ||
38 | int ds_touch_bit(struct ds_device *, u8, u8 *); | ||
39 | int ds_read_byte(struct ds_device *, u8 *); | ||
40 | int ds_read_bit(struct ds_device *, u8 *); | ||
41 | int ds_write_byte(struct ds_device *, u8); | ||
42 | int ds_write_bit(struct ds_device *, u8); | ||
43 | static int ds_start_pulse(struct ds_device *, int); | ||
44 | int ds_reset(struct ds_device *, struct ds_status *); | ||
45 | struct ds_device * ds_get_device(void); | ||
46 | void ds_put_device(struct ds_device *); | ||
47 | |||
48 | static inline void ds_dump_status(unsigned char *, unsigned char *, int); | 167 | static inline void ds_dump_status(unsigned char *, unsigned char *, int); |
49 | static int ds_send_control(struct ds_device *, u16, u16); | 168 | static int ds_send_control(struct ds_device *, u16, u16); |
50 | static int ds_send_control_mode(struct ds_device *, u16, u16); | ||
51 | static int ds_send_control_cmd(struct ds_device *, u16, u16); | 169 | static int ds_send_control_cmd(struct ds_device *, u16, u16); |
52 | 170 | ||
171 | static LIST_HEAD(ds_devices); | ||
172 | static DEFINE_MUTEX(ds_mutex); | ||
53 | 173 | ||
54 | static struct usb_driver ds_driver = { | 174 | static struct usb_driver ds_driver = { |
55 | .name = "DS9490R", | 175 | .name = "DS9490R", |
@@ -58,20 +178,6 @@ static struct usb_driver ds_driver = { | |||
58 | .id_table = ds_id_table, | 178 | .id_table = ds_id_table, |
59 | }; | 179 | }; |
60 | 180 | ||
61 | static struct ds_device *ds_dev; | ||
62 | |||
63 | struct ds_device * ds_get_device(void) | ||
64 | { | ||
65 | if (ds_dev) | ||
66 | atomic_inc(&ds_dev->refcnt); | ||
67 | return ds_dev; | ||
68 | } | ||
69 | |||
70 | void ds_put_device(struct ds_device *dev) | ||
71 | { | ||
72 | atomic_dec(&dev->refcnt); | ||
73 | } | ||
74 | |||
75 | static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) | 181 | static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) |
76 | { | 182 | { |
77 | int err; | 183 | int err; |
@@ -86,7 +192,7 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index) | |||
86 | 192 | ||
87 | return err; | 193 | return err; |
88 | } | 194 | } |
89 | 195 | #if 0 | |
90 | static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) | 196 | static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) |
91 | { | 197 | { |
92 | int err; | 198 | int err; |
@@ -101,7 +207,7 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index) | |||
101 | 207 | ||
102 | return err; | 208 | return err; |
103 | } | 209 | } |
104 | 210 | #endif | |
105 | static int ds_send_control(struct ds_device *dev, u16 value, u16 index) | 211 | static int ds_send_control(struct ds_device *dev, u16 value, u16 index) |
106 | { | 212 | { |
107 | int err; | 213 | int err; |
@@ -324,7 +430,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st) | |||
324 | return 0; | 430 | return 0; |
325 | } | 431 | } |
326 | 432 | ||
327 | int ds_reset(struct ds_device *dev, struct ds_status *st) | 433 | static int ds_reset(struct ds_device *dev, struct ds_status *st) |
328 | { | 434 | { |
329 | int err; | 435 | int err; |
330 | 436 | ||
@@ -345,7 +451,7 @@ int ds_reset(struct ds_device *dev, struct ds_status *st) | |||
345 | } | 451 | } |
346 | 452 | ||
347 | #if 0 | 453 | #if 0 |
348 | int ds_set_speed(struct ds_device *dev, int speed) | 454 | static int ds_set_speed(struct ds_device *dev, int speed) |
349 | { | 455 | { |
350 | int err; | 456 | int err; |
351 | 457 | ||
@@ -395,7 +501,7 @@ static int ds_start_pulse(struct ds_device *dev, int delay) | |||
395 | return err; | 501 | return err; |
396 | } | 502 | } |
397 | 503 | ||
398 | int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) | 504 | static int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) |
399 | { | 505 | { |
400 | int err, count; | 506 | int err, count; |
401 | struct ds_status st; | 507 | struct ds_status st; |
@@ -427,7 +533,7 @@ int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit) | |||
427 | return 0; | 533 | return 0; |
428 | } | 534 | } |
429 | 535 | ||
430 | int ds_write_bit(struct ds_device *dev, u8 bit) | 536 | static int ds_write_bit(struct ds_device *dev, u8 bit) |
431 | { | 537 | { |
432 | int err; | 538 | int err; |
433 | struct ds_status st; | 539 | struct ds_status st; |
@@ -441,7 +547,7 @@ int ds_write_bit(struct ds_device *dev, u8 bit) | |||
441 | return 0; | 547 | return 0; |
442 | } | 548 | } |
443 | 549 | ||
444 | int ds_write_byte(struct ds_device *dev, u8 byte) | 550 | static int ds_write_byte(struct ds_device *dev, u8 byte) |
445 | { | 551 | { |
446 | int err; | 552 | int err; |
447 | struct ds_status st; | 553 | struct ds_status st; |
@@ -464,26 +570,7 @@ int ds_write_byte(struct ds_device *dev, u8 byte) | |||
464 | return !(byte == rbyte); | 570 | return !(byte == rbyte); |
465 | } | 571 | } |
466 | 572 | ||
467 | int ds_read_bit(struct ds_device *dev, u8 *bit) | 573 | static int ds_read_byte(struct ds_device *dev, u8 *byte) |
468 | { | ||
469 | int err; | ||
470 | |||
471 | err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE); | ||
472 | if (err) | ||
473 | return err; | ||
474 | |||
475 | err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_SPU | COMM_D, 0); | ||
476 | if (err) | ||
477 | return err; | ||
478 | |||
479 | err = ds_recv_data(dev, bit, sizeof(*bit)); | ||
480 | if (err < 0) | ||
481 | return err; | ||
482 | |||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | int ds_read_byte(struct ds_device *dev, u8 *byte) | ||
487 | { | 574 | { |
488 | int err; | 575 | int err; |
489 | struct ds_status st; | 576 | struct ds_status st; |
@@ -501,7 +588,7 @@ int ds_read_byte(struct ds_device *dev, u8 *byte) | |||
501 | return 0; | 588 | return 0; |
502 | } | 589 | } |
503 | 590 | ||
504 | int ds_read_block(struct ds_device *dev, u8 *buf, int len) | 591 | static int ds_read_block(struct ds_device *dev, u8 *buf, int len) |
505 | { | 592 | { |
506 | struct ds_status st; | 593 | struct ds_status st; |
507 | int err; | 594 | int err; |
@@ -527,7 +614,7 @@ int ds_read_block(struct ds_device *dev, u8 *buf, int len) | |||
527 | return err; | 614 | return err; |
528 | } | 615 | } |
529 | 616 | ||
530 | int ds_write_block(struct ds_device *dev, u8 *buf, int len) | 617 | static int ds_write_block(struct ds_device *dev, u8 *buf, int len) |
531 | { | 618 | { |
532 | int err; | 619 | int err; |
533 | struct ds_status st; | 620 | struct ds_status st; |
@@ -555,7 +642,7 @@ int ds_write_block(struct ds_device *dev, u8 *buf, int len) | |||
555 | 642 | ||
556 | #if 0 | 643 | #if 0 |
557 | 644 | ||
558 | int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) | 645 | static int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int conditional_search) |
559 | { | 646 | { |
560 | int err; | 647 | int err; |
561 | u16 value, index; | 648 | u16 value, index; |
@@ -584,7 +671,7 @@ int ds_search(struct ds_device *dev, u64 init, u64 *buf, u8 id_number, int condi | |||
584 | return err/8; | 671 | return err/8; |
585 | } | 672 | } |
586 | 673 | ||
587 | int ds_match_access(struct ds_device *dev, u64 init) | 674 | static int ds_match_access(struct ds_device *dev, u64 init) |
588 | { | 675 | { |
589 | int err; | 676 | int err; |
590 | struct ds_status st; | 677 | struct ds_status st; |
@@ -604,7 +691,7 @@ int ds_match_access(struct ds_device *dev, u64 init) | |||
604 | return 0; | 691 | return 0; |
605 | } | 692 | } |
606 | 693 | ||
607 | int ds_set_path(struct ds_device *dev, u64 init) | 694 | static int ds_set_path(struct ds_device *dev, u64 init) |
608 | { | 695 | { |
609 | int err; | 696 | int err; |
610 | struct ds_status st; | 697 | struct ds_status st; |
@@ -630,45 +717,156 @@ int ds_set_path(struct ds_device *dev, u64 init) | |||
630 | 717 | ||
631 | #endif /* 0 */ | 718 | #endif /* 0 */ |
632 | 719 | ||
720 | static u8 ds9490r_touch_bit(void *data, u8 bit) | ||
721 | { | ||
722 | u8 ret; | ||
723 | struct ds_device *dev = data; | ||
724 | |||
725 | if (ds_touch_bit(dev, bit, &ret)) | ||
726 | return 0; | ||
727 | |||
728 | return ret; | ||
729 | } | ||
730 | |||
731 | static void ds9490r_write_bit(void *data, u8 bit) | ||
732 | { | ||
733 | struct ds_device *dev = data; | ||
734 | |||
735 | ds_write_bit(dev, bit); | ||
736 | } | ||
737 | |||
738 | static void ds9490r_write_byte(void *data, u8 byte) | ||
739 | { | ||
740 | struct ds_device *dev = data; | ||
741 | |||
742 | ds_write_byte(dev, byte); | ||
743 | } | ||
744 | |||
745 | static u8 ds9490r_read_bit(void *data) | ||
746 | { | ||
747 | struct ds_device *dev = data; | ||
748 | int err; | ||
749 | u8 bit = 0; | ||
750 | |||
751 | err = ds_touch_bit(dev, 1, &bit); | ||
752 | if (err) | ||
753 | return 0; | ||
754 | |||
755 | return bit & 1; | ||
756 | } | ||
757 | |||
758 | static u8 ds9490r_read_byte(void *data) | ||
759 | { | ||
760 | struct ds_device *dev = data; | ||
761 | int err; | ||
762 | u8 byte = 0; | ||
763 | |||
764 | err = ds_read_byte(dev, &byte); | ||
765 | if (err) | ||
766 | return 0; | ||
767 | |||
768 | return byte; | ||
769 | } | ||
770 | |||
771 | static void ds9490r_write_block(void *data, const u8 *buf, int len) | ||
772 | { | ||
773 | struct ds_device *dev = data; | ||
774 | |||
775 | ds_write_block(dev, (u8 *)buf, len); | ||
776 | } | ||
777 | |||
778 | static u8 ds9490r_read_block(void *data, u8 *buf, int len) | ||
779 | { | ||
780 | struct ds_device *dev = data; | ||
781 | int err; | ||
782 | |||
783 | err = ds_read_block(dev, buf, len); | ||
784 | if (err < 0) | ||
785 | return 0; | ||
786 | |||
787 | return len; | ||
788 | } | ||
789 | |||
790 | static u8 ds9490r_reset(void *data) | ||
791 | { | ||
792 | struct ds_device *dev = data; | ||
793 | struct ds_status st; | ||
794 | int err; | ||
795 | |||
796 | memset(&st, 0, sizeof(st)); | ||
797 | |||
798 | err = ds_reset(dev, &st); | ||
799 | if (err) | ||
800 | return 1; | ||
801 | |||
802 | return 0; | ||
803 | } | ||
804 | |||
805 | static int ds_w1_init(struct ds_device *dev) | ||
806 | { | ||
807 | memset(&dev->master, 0, sizeof(struct w1_bus_master)); | ||
808 | |||
809 | dev->master.data = dev; | ||
810 | dev->master.touch_bit = &ds9490r_touch_bit; | ||
811 | dev->master.read_bit = &ds9490r_read_bit; | ||
812 | dev->master.write_bit = &ds9490r_write_bit; | ||
813 | dev->master.read_byte = &ds9490r_read_byte; | ||
814 | dev->master.write_byte = &ds9490r_write_byte; | ||
815 | dev->master.read_block = &ds9490r_read_block; | ||
816 | dev->master.write_block = &ds9490r_write_block; | ||
817 | dev->master.reset_bus = &ds9490r_reset; | ||
818 | |||
819 | return w1_add_master_device(&dev->master); | ||
820 | } | ||
821 | |||
822 | static void ds_w1_fini(struct ds_device *dev) | ||
823 | { | ||
824 | w1_remove_master_device(&dev->master); | ||
825 | } | ||
826 | |||
633 | static int ds_probe(struct usb_interface *intf, | 827 | static int ds_probe(struct usb_interface *intf, |
634 | const struct usb_device_id *udev_id) | 828 | const struct usb_device_id *udev_id) |
635 | { | 829 | { |
636 | struct usb_device *udev = interface_to_usbdev(intf); | 830 | struct usb_device *udev = interface_to_usbdev(intf); |
637 | struct usb_endpoint_descriptor *endpoint; | 831 | struct usb_endpoint_descriptor *endpoint; |
638 | struct usb_host_interface *iface_desc; | 832 | struct usb_host_interface *iface_desc; |
833 | struct ds_device *dev; | ||
639 | int i, err; | 834 | int i, err; |
640 | 835 | ||
641 | ds_dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); | 836 | dev = kmalloc(sizeof(struct ds_device), GFP_KERNEL); |
642 | if (!ds_dev) { | 837 | if (!dev) { |
643 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); | 838 | printk(KERN_INFO "Failed to allocate new DS9490R structure.\n"); |
644 | return -ENOMEM; | 839 | return -ENOMEM; |
645 | } | 840 | } |
841 | dev->udev = usb_get_dev(udev); | ||
842 | if (!dev->udev) { | ||
843 | err = -ENOMEM; | ||
844 | goto err_out_free; | ||
845 | } | ||
846 | memset(dev->ep, 0, sizeof(dev->ep)); | ||
646 | 847 | ||
647 | ds_dev->udev = usb_get_dev(udev); | 848 | usb_set_intfdata(intf, dev); |
648 | usb_set_intfdata(intf, ds_dev); | ||
649 | 849 | ||
650 | err = usb_set_interface(ds_dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); | 850 | err = usb_set_interface(dev->udev, intf->altsetting[0].desc.bInterfaceNumber, 3); |
651 | if (err) { | 851 | if (err) { |
652 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", | 852 | printk(KERN_ERR "Failed to set alternative setting 3 for %d interface: err=%d.\n", |
653 | intf->altsetting[0].desc.bInterfaceNumber, err); | 853 | intf->altsetting[0].desc.bInterfaceNumber, err); |
654 | return err; | 854 | goto err_out_clear; |
655 | } | 855 | } |
656 | 856 | ||
657 | err = usb_reset_configuration(ds_dev->udev); | 857 | err = usb_reset_configuration(dev->udev); |
658 | if (err) { | 858 | if (err) { |
659 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); | 859 | printk(KERN_ERR "Failed to reset configuration: err=%d.\n", err); |
660 | return err; | 860 | goto err_out_clear; |
661 | } | 861 | } |
662 | 862 | ||
663 | iface_desc = &intf->altsetting[0]; | 863 | iface_desc = &intf->altsetting[0]; |
664 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { | 864 | if (iface_desc->desc.bNumEndpoints != NUM_EP-1) { |
665 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); | 865 | printk(KERN_INFO "Num endpoints=%d. It is not DS9490R.\n", iface_desc->desc.bNumEndpoints); |
666 | return -ENODEV; | 866 | err = -EINVAL; |
867 | goto err_out_clear; | ||
667 | } | 868 | } |
668 | 869 | ||
669 | atomic_set(&ds_dev->refcnt, 0); | ||
670 | memset(ds_dev->ep, 0, sizeof(ds_dev->ep)); | ||
671 | |||
672 | /* | 870 | /* |
673 | * This loop doesn'd show control 0 endpoint, | 871 | * This loop doesn'd show control 0 endpoint, |
674 | * so we will fill only 1-3 endpoints entry. | 872 | * so we will fill only 1-3 endpoints entry. |
@@ -676,54 +874,31 @@ static int ds_probe(struct usb_interface *intf, | |||
676 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | 874 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { |
677 | endpoint = &iface_desc->endpoint[i].desc; | 875 | endpoint = &iface_desc->endpoint[i].desc; |
678 | 876 | ||
679 | ds_dev->ep[i+1] = endpoint->bEndpointAddress; | 877 | dev->ep[i+1] = endpoint->bEndpointAddress; |
680 | 878 | #if 0 | |
681 | printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", | 879 | printk("%d: addr=%x, size=%d, dir=%s, type=%x\n", |
682 | i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), | 880 | i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize), |
683 | (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", | 881 | (endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT", |
684 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 882 | endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); |
883 | #endif | ||
685 | } | 884 | } |
686 | 885 | ||
687 | #if 0 | 886 | err = ds_w1_init(dev); |
688 | { | 887 | if (err) |
689 | int err, i; | 888 | goto err_out_clear; |
690 | u64 buf[3]; | ||
691 | u64 init=0xb30000002078ee81ull; | ||
692 | struct ds_status st; | ||
693 | |||
694 | ds_reset(ds_dev, &st); | ||
695 | err = ds_search(ds_dev, init, buf, 3, 0); | ||
696 | if (err < 0) | ||
697 | return err; | ||
698 | for (i=0; i<err; ++i) | ||
699 | printk("%d: %llx\n", i, buf[i]); | ||
700 | |||
701 | printk("Resetting...\n"); | ||
702 | ds_reset(ds_dev, &st); | ||
703 | printk("Setting path for %llx.\n", init); | ||
704 | err = ds_set_path(ds_dev, init); | ||
705 | if (err) | ||
706 | return err; | ||
707 | printk("Calling MATCH_ACCESS.\n"); | ||
708 | err = ds_match_access(ds_dev, init); | ||
709 | if (err) | ||
710 | return err; | ||
711 | |||
712 | printk("Searching the bus...\n"); | ||
713 | err = ds_search(ds_dev, init, buf, 3, 0); | ||
714 | |||
715 | printk("ds_search() returned %d\n", err); | ||
716 | |||
717 | if (err < 0) | ||
718 | return err; | ||
719 | for (i=0; i<err; ++i) | ||
720 | printk("%d: %llx\n", i, buf[i]); | ||
721 | 889 | ||
722 | return 0; | 890 | mutex_lock(&ds_mutex); |
723 | } | 891 | list_add_tail(&dev->ds_entry, &ds_devices); |
724 | #endif | 892 | mutex_unlock(&ds_mutex); |
725 | 893 | ||
726 | return 0; | 894 | return 0; |
895 | |||
896 | err_out_clear: | ||
897 | usb_set_intfdata(intf, NULL); | ||
898 | usb_put_dev(dev->udev); | ||
899 | err_out_free: | ||
900 | kfree(dev); | ||
901 | return err; | ||
727 | } | 902 | } |
728 | 903 | ||
729 | static void ds_disconnect(struct usb_interface *intf) | 904 | static void ds_disconnect(struct usb_interface *intf) |
@@ -731,19 +906,19 @@ static void ds_disconnect(struct usb_interface *intf) | |||
731 | struct ds_device *dev; | 906 | struct ds_device *dev; |
732 | 907 | ||
733 | dev = usb_get_intfdata(intf); | 908 | dev = usb_get_intfdata(intf); |
734 | usb_set_intfdata(intf, NULL); | 909 | if (!dev) |
910 | return; | ||
735 | 911 | ||
736 | while (atomic_read(&dev->refcnt)) { | 912 | mutex_lock(&ds_mutex); |
737 | printk(KERN_INFO "Waiting for DS to become free: refcnt=%d.\n", | 913 | list_del(&dev->ds_entry); |
738 | atomic_read(&dev->refcnt)); | 914 | mutex_unlock(&ds_mutex); |
739 | 915 | ||
740 | if (msleep_interruptible(1000)) | 916 | ds_w1_fini(dev); |
741 | flush_signals(current); | 917 | |
742 | } | 918 | usb_set_intfdata(intf, NULL); |
743 | 919 | ||
744 | usb_put_dev(dev->udev); | 920 | usb_put_dev(dev->udev); |
745 | kfree(dev); | 921 | kfree(dev); |
746 | ds_dev = NULL; | ||
747 | } | 922 | } |
748 | 923 | ||
749 | static int ds_init(void) | 924 | static int ds_init(void) |
@@ -769,27 +944,4 @@ module_exit(ds_fini); | |||
769 | 944 | ||
770 | MODULE_LICENSE("GPL"); | 945 | MODULE_LICENSE("GPL"); |
771 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | 946 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); |
772 | 947 | MODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)"); | |
773 | EXPORT_SYMBOL(ds_touch_bit); | ||
774 | EXPORT_SYMBOL(ds_read_byte); | ||
775 | EXPORT_SYMBOL(ds_read_bit); | ||
776 | EXPORT_SYMBOL(ds_read_block); | ||
777 | EXPORT_SYMBOL(ds_write_byte); | ||
778 | EXPORT_SYMBOL(ds_write_bit); | ||
779 | EXPORT_SYMBOL(ds_write_block); | ||
780 | EXPORT_SYMBOL(ds_reset); | ||
781 | EXPORT_SYMBOL(ds_get_device); | ||
782 | EXPORT_SYMBOL(ds_put_device); | ||
783 | |||
784 | /* | ||
785 | * This functions can be used for EEPROM programming, | ||
786 | * when driver will be included into mainline this will | ||
787 | * require uncommenting. | ||
788 | */ | ||
789 | #if 0 | ||
790 | EXPORT_SYMBOL(ds_start_pulse); | ||
791 | EXPORT_SYMBOL(ds_set_speed); | ||
792 | EXPORT_SYMBOL(ds_detect); | ||
793 | EXPORT_SYMBOL(ds_stop_pulse); | ||
794 | EXPORT_SYMBOL(ds_search); | ||
795 | #endif | ||
diff --git a/drivers/w1/masters/ds_w1_bridge.c b/drivers/w1/masters/ds_w1_bridge.c deleted file mode 100644 index 5d30783a3eb6..000000000000 --- a/drivers/w1/masters/ds_w1_bridge.c +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /* | ||
2 | * ds_w1_bridge.c | ||
3 | * | ||
4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> | ||
5 | * | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/types.h> | ||
24 | |||
25 | #include "../w1.h" | ||
26 | #include "../w1_int.h" | ||
27 | #include "dscore.h" | ||
28 | |||
29 | static struct ds_device *ds_dev; | ||
30 | static struct w1_bus_master *ds_bus_master; | ||
31 | |||
32 | static u8 ds9490r_touch_bit(void *data, u8 bit) | ||
33 | { | ||
34 | u8 ret; | ||
35 | struct ds_device *dev = data; | ||
36 | |||
37 | if (ds_touch_bit(dev, bit, &ret)) | ||
38 | return 0; | ||
39 | |||
40 | return ret; | ||
41 | } | ||
42 | |||
43 | static void ds9490r_write_bit(void *data, u8 bit) | ||
44 | { | ||
45 | struct ds_device *dev = data; | ||
46 | |||
47 | ds_write_bit(dev, bit); | ||
48 | } | ||
49 | |||
50 | static void ds9490r_write_byte(void *data, u8 byte) | ||
51 | { | ||
52 | struct ds_device *dev = data; | ||
53 | |||
54 | ds_write_byte(dev, byte); | ||
55 | } | ||
56 | |||
57 | static u8 ds9490r_read_bit(void *data) | ||
58 | { | ||
59 | struct ds_device *dev = data; | ||
60 | int err; | ||
61 | u8 bit = 0; | ||
62 | |||
63 | err = ds_touch_bit(dev, 1, &bit); | ||
64 | if (err) | ||
65 | return 0; | ||
66 | //err = ds_read_bit(dev, &bit); | ||
67 | //if (err) | ||
68 | // return 0; | ||
69 | |||
70 | return bit & 1; | ||
71 | } | ||
72 | |||
73 | static u8 ds9490r_read_byte(void *data) | ||
74 | { | ||
75 | struct ds_device *dev = data; | ||
76 | int err; | ||
77 | u8 byte = 0; | ||
78 | |||
79 | err = ds_read_byte(dev, &byte); | ||
80 | if (err) | ||
81 | return 0; | ||
82 | |||
83 | return byte; | ||
84 | } | ||
85 | |||
86 | static void ds9490r_write_block(void *data, const u8 *buf, int len) | ||
87 | { | ||
88 | struct ds_device *dev = data; | ||
89 | |||
90 | ds_write_block(dev, (u8 *)buf, len); | ||
91 | } | ||
92 | |||
93 | static u8 ds9490r_read_block(void *data, u8 *buf, int len) | ||
94 | { | ||
95 | struct ds_device *dev = data; | ||
96 | int err; | ||
97 | |||
98 | err = ds_read_block(dev, buf, len); | ||
99 | if (err < 0) | ||
100 | return 0; | ||
101 | |||
102 | return len; | ||
103 | } | ||
104 | |||
105 | static u8 ds9490r_reset(void *data) | ||
106 | { | ||
107 | struct ds_device *dev = data; | ||
108 | struct ds_status st; | ||
109 | int err; | ||
110 | |||
111 | memset(&st, 0, sizeof(st)); | ||
112 | |||
113 | err = ds_reset(dev, &st); | ||
114 | if (err) | ||
115 | return 1; | ||
116 | |||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static int __devinit ds_w1_init(void) | ||
121 | { | ||
122 | int err; | ||
123 | |||
124 | ds_bus_master = kmalloc(sizeof(*ds_bus_master), GFP_KERNEL); | ||
125 | if (!ds_bus_master) { | ||
126 | printk(KERN_ERR "Failed to allocate DS9490R USB<->W1 bus_master structure.\n"); | ||
127 | return -ENOMEM; | ||
128 | } | ||
129 | |||
130 | ds_dev = ds_get_device(); | ||
131 | if (!ds_dev) { | ||
132 | printk(KERN_ERR "DS9490R is not registered.\n"); | ||
133 | err = -ENODEV; | ||
134 | goto err_out_free_bus_master; | ||
135 | } | ||
136 | |||
137 | memset(ds_bus_master, 0, sizeof(*ds_bus_master)); | ||
138 | |||
139 | ds_bus_master->data = ds_dev; | ||
140 | ds_bus_master->touch_bit = &ds9490r_touch_bit; | ||
141 | ds_bus_master->read_bit = &ds9490r_read_bit; | ||
142 | ds_bus_master->write_bit = &ds9490r_write_bit; | ||
143 | ds_bus_master->read_byte = &ds9490r_read_byte; | ||
144 | ds_bus_master->write_byte = &ds9490r_write_byte; | ||
145 | ds_bus_master->read_block = &ds9490r_read_block; | ||
146 | ds_bus_master->write_block = &ds9490r_write_block; | ||
147 | ds_bus_master->reset_bus = &ds9490r_reset; | ||
148 | |||
149 | err = w1_add_master_device(ds_bus_master); | ||
150 | if (err) | ||
151 | goto err_out_put_device; | ||
152 | |||
153 | return 0; | ||
154 | |||
155 | err_out_put_device: | ||
156 | ds_put_device(ds_dev); | ||
157 | err_out_free_bus_master: | ||
158 | kfree(ds_bus_master); | ||
159 | |||
160 | return err; | ||
161 | } | ||
162 | |||
163 | static void __devexit ds_w1_fini(void) | ||
164 | { | ||
165 | w1_remove_master_device(ds_bus_master); | ||
166 | ds_put_device(ds_dev); | ||
167 | kfree(ds_bus_master); | ||
168 | } | ||
169 | |||
170 | module_init(ds_w1_init); | ||
171 | module_exit(ds_w1_fini); | ||
172 | |||
173 | MODULE_LICENSE("GPL"); | ||
174 | MODULE_AUTHOR("Evgeniy Polyakov <johnpol@2ka.mipt.ru>"); | ||
diff --git a/drivers/w1/masters/dscore.h b/drivers/w1/masters/dscore.h deleted file mode 100644 index 6cf5671d6ebe..000000000000 --- a/drivers/w1/masters/dscore.h +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * dscore.h | ||
3 | * | ||
4 | * Copyright (c) 2004 Evgeniy Polyakov <johnpol@2ka.mipt.ru> | ||
5 | * | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef __DSCORE_H | ||
23 | #define __DSCORE_H | ||
24 | |||
25 | #include <linux/usb.h> | ||
26 | #include <asm/atomic.h> | ||
27 | |||
28 | /* COMMAND TYPE CODES */ | ||
29 | #define CONTROL_CMD 0x00 | ||
30 | #define COMM_CMD 0x01 | ||
31 | #define MODE_CMD 0x02 | ||
32 | |||
33 | /* CONTROL COMMAND CODES */ | ||
34 | #define CTL_RESET_DEVICE 0x0000 | ||
35 | #define CTL_START_EXE 0x0001 | ||
36 | #define CTL_RESUME_EXE 0x0002 | ||
37 | #define CTL_HALT_EXE_IDLE 0x0003 | ||
38 | #define CTL_HALT_EXE_DONE 0x0004 | ||
39 | #define CTL_FLUSH_COMM_CMDS 0x0007 | ||
40 | #define CTL_FLUSH_RCV_BUFFER 0x0008 | ||
41 | #define CTL_FLUSH_XMT_BUFFER 0x0009 | ||
42 | #define CTL_GET_COMM_CMDS 0x000A | ||
43 | |||
44 | /* MODE COMMAND CODES */ | ||
45 | #define MOD_PULSE_EN 0x0000 | ||
46 | #define MOD_SPEED_CHANGE_EN 0x0001 | ||
47 | #define MOD_1WIRE_SPEED 0x0002 | ||
48 | #define MOD_STRONG_PU_DURATION 0x0003 | ||
49 | #define MOD_PULLDOWN_SLEWRATE 0x0004 | ||
50 | #define MOD_PROG_PULSE_DURATION 0x0005 | ||
51 | #define MOD_WRITE1_LOWTIME 0x0006 | ||
52 | #define MOD_DSOW0_TREC 0x0007 | ||
53 | |||
54 | /* COMMUNICATION COMMAND CODES */ | ||
55 | #define COMM_ERROR_ESCAPE 0x0601 | ||
56 | #define COMM_SET_DURATION 0x0012 | ||
57 | #define COMM_BIT_IO 0x0020 | ||
58 | #define COMM_PULSE 0x0030 | ||
59 | #define COMM_1_WIRE_RESET 0x0042 | ||
60 | #define COMM_BYTE_IO 0x0052 | ||
61 | #define COMM_MATCH_ACCESS 0x0064 | ||
62 | #define COMM_BLOCK_IO 0x0074 | ||
63 | #define COMM_READ_STRAIGHT 0x0080 | ||
64 | #define COMM_DO_RELEASE 0x6092 | ||
65 | #define COMM_SET_PATH 0x00A2 | ||
66 | #define COMM_WRITE_SRAM_PAGE 0x00B2 | ||
67 | #define COMM_WRITE_EPROM 0x00C4 | ||
68 | #define COMM_READ_CRC_PROT_PAGE 0x00D4 | ||
69 | #define COMM_READ_REDIRECT_PAGE_CRC 0x21E4 | ||
70 | #define COMM_SEARCH_ACCESS 0x00F4 | ||
71 | |||
72 | /* Communication command bits */ | ||
73 | #define COMM_TYPE 0x0008 | ||
74 | #define COMM_SE 0x0008 | ||
75 | #define COMM_D 0x0008 | ||
76 | #define COMM_Z 0x0008 | ||
77 | #define COMM_CH 0x0008 | ||
78 | #define COMM_SM 0x0008 | ||
79 | #define COMM_R 0x0008 | ||
80 | #define COMM_IM 0x0001 | ||
81 | |||
82 | #define COMM_PS 0x4000 | ||
83 | #define COMM_PST 0x4000 | ||
84 | #define COMM_CIB 0x4000 | ||
85 | #define COMM_RTS 0x4000 | ||
86 | #define COMM_DT 0x2000 | ||
87 | #define COMM_SPU 0x1000 | ||
88 | #define COMM_F 0x0800 | ||
89 | #define COMM_NTP 0x0400 | ||
90 | #define COMM_ICP 0x0200 | ||
91 | #define COMM_RST 0x0100 | ||
92 | |||
93 | #define PULSE_PROG 0x01 | ||
94 | #define PULSE_SPUE 0x02 | ||
95 | |||
96 | #define BRANCH_MAIN 0xCC | ||
97 | #define BRANCH_AUX 0x33 | ||
98 | |||
99 | /* | ||
100 | * Duration of the strong pull-up pulse in milliseconds. | ||
101 | */ | ||
102 | #define PULLUP_PULSE_DURATION 750 | ||
103 | |||
104 | /* Status flags */ | ||
105 | #define ST_SPUA 0x01 /* Strong Pull-up is active */ | ||
106 | #define ST_PRGA 0x02 /* 12V programming pulse is being generated */ | ||
107 | #define ST_12VP 0x04 /* external 12V programming voltage is present */ | ||
108 | #define ST_PMOD 0x08 /* DS2490 powered from USB and external sources */ | ||
109 | #define ST_HALT 0x10 /* DS2490 is currently halted */ | ||
110 | #define ST_IDLE 0x20 /* DS2490 is currently idle */ | ||
111 | #define ST_EPOF 0x80 | ||
112 | |||
113 | #define SPEED_NORMAL 0x00 | ||
114 | #define SPEED_FLEXIBLE 0x01 | ||
115 | #define SPEED_OVERDRIVE 0x02 | ||
116 | |||
117 | #define NUM_EP 4 | ||
118 | #define EP_CONTROL 0 | ||
119 | #define EP_STATUS 1 | ||
120 | #define EP_DATA_OUT 2 | ||
121 | #define EP_DATA_IN 3 | ||
122 | |||
123 | struct ds_device | ||
124 | { | ||
125 | struct usb_device *udev; | ||
126 | struct usb_interface *intf; | ||
127 | |||
128 | int ep[NUM_EP]; | ||
129 | |||
130 | atomic_t refcnt; | ||
131 | }; | ||
132 | |||
133 | struct ds_status | ||
134 | { | ||
135 | u8 enable; | ||
136 | u8 speed; | ||
137 | u8 pullup_dur; | ||
138 | u8 ppuls_dur; | ||
139 | u8 pulldown_slew; | ||
140 | u8 write1_time; | ||
141 | u8 write0_time; | ||
142 | u8 reserved0; | ||
143 | u8 status; | ||
144 | u8 command0; | ||
145 | u8 command1; | ||
146 | u8 command_buffer_status; | ||
147 | u8 data_out_buffer_status; | ||
148 | u8 data_in_buffer_status; | ||
149 | u8 reserved1; | ||
150 | u8 reserved2; | ||
151 | |||
152 | }; | ||
153 | |||
154 | int ds_touch_bit(struct ds_device *, u8, u8 *); | ||
155 | int ds_read_byte(struct ds_device *, u8 *); | ||
156 | int ds_read_bit(struct ds_device *, u8 *); | ||
157 | int ds_write_byte(struct ds_device *, u8); | ||
158 | int ds_write_bit(struct ds_device *, u8); | ||
159 | int ds_reset(struct ds_device *, struct ds_status *); | ||
160 | struct ds_device * ds_get_device(void); | ||
161 | void ds_put_device(struct ds_device *); | ||
162 | int ds_write_block(struct ds_device *, u8 *, int); | ||
163 | int ds_read_block(struct ds_device *, u8 *, int); | ||
164 | |||
165 | #endif /* __DSCORE_H */ | ||
166 | |||
diff --git a/drivers/w1/slaves/Kconfig b/drivers/w1/slaves/Kconfig index f9d4c91fc533..d18d6424cd21 100644 --- a/drivers/w1/slaves/Kconfig +++ b/drivers/w1/slaves/Kconfig | |||
@@ -28,7 +28,7 @@ config W1_SLAVE_DS2433 | |||
28 | 28 | ||
29 | config W1_SLAVE_DS2433_CRC | 29 | config W1_SLAVE_DS2433_CRC |
30 | bool "Protect DS2433 data with a CRC16" | 30 | bool "Protect DS2433 data with a CRC16" |
31 | depends on W1_DS2433 | 31 | depends on W1_SLAVE_DS2433 |
32 | select CRC16 | 32 | select CRC16 |
33 | help | 33 | help |
34 | Say Y here to protect DS2433 data with a CRC16. | 34 | Say Y here to protect DS2433 data with a CRC16. |
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index fb118be789ea..2ac238f1480e 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #include "../w1.h" | 24 | #include "../w1.h" |
25 | #include "../w1_io.h" | ||
26 | #include "../w1_int.h" | 25 | #include "../w1_int.h" |
27 | #include "../w1_family.h" | 26 | #include "../w1_family.h" |
28 | 27 | ||
@@ -106,11 +105,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, | |||
106 | if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) | 105 | if ((count = w1_f23_fix_count(off, count, W1_EEPROM_SIZE)) == 0) |
107 | return 0; | 106 | return 0; |
108 | 107 | ||
109 | atomic_inc(&sl->refcnt); | 108 | mutex_lock(&sl->master->mutex); |
110 | if (down_interruptible(&sl->master->mutex)) { | ||
111 | count = 0; | ||
112 | goto out_dec; | ||
113 | } | ||
114 | 109 | ||
115 | #ifdef CONFIG_W1_F23_CRC | 110 | #ifdef CONFIG_W1_F23_CRC |
116 | 111 | ||
@@ -141,9 +136,7 @@ static ssize_t w1_f23_read_bin(struct kobject *kobj, char *buf, loff_t off, | |||
141 | #endif /* CONFIG_W1_F23_CRC */ | 136 | #endif /* CONFIG_W1_F23_CRC */ |
142 | 137 | ||
143 | out_up: | 138 | out_up: |
144 | up(&sl->master->mutex); | 139 | mutex_unlock(&sl->master->mutex); |
145 | out_dec: | ||
146 | atomic_dec(&sl->refcnt); | ||
147 | 140 | ||
148 | return count; | 141 | return count; |
149 | } | 142 | } |
@@ -232,11 +225,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off, | |||
232 | } | 225 | } |
233 | #endif /* CONFIG_W1_F23_CRC */ | 226 | #endif /* CONFIG_W1_F23_CRC */ |
234 | 227 | ||
235 | atomic_inc(&sl->refcnt); | 228 | mutex_lock(&sl->master->mutex); |
236 | if (down_interruptible(&sl->master->mutex)) { | ||
237 | count = 0; | ||
238 | goto out_dec; | ||
239 | } | ||
240 | 229 | ||
241 | /* Can only write data to one page at a time */ | 230 | /* Can only write data to one page at a time */ |
242 | idx = 0; | 231 | idx = 0; |
@@ -254,9 +243,7 @@ static ssize_t w1_f23_write_bin(struct kobject *kobj, char *buf, loff_t off, | |||
254 | } | 243 | } |
255 | 244 | ||
256 | out_up: | 245 | out_up: |
257 | up(&sl->master->mutex); | 246 | mutex_unlock(&sl->master->mutex); |
258 | out_dec: | ||
259 | atomic_dec(&sl->refcnt); | ||
260 | 247 | ||
261 | return count; | 248 | return count; |
262 | } | 249 | } |
diff --git a/drivers/w1/slaves/w1_smem.c b/drivers/w1/slaves/w1_smem.c index c6d3be54f94c..cc8c02e92593 100644 --- a/drivers/w1/slaves/w1_smem.c +++ b/drivers/w1/slaves/w1_smem.c | |||
@@ -28,7 +28,6 @@ | |||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | #include "../w1.h" | 30 | #include "../w1.h" |
31 | #include "../w1_io.h" | ||
32 | #include "../w1_int.h" | 31 | #include "../w1_int.h" |
33 | #include "../w1_family.h" | 32 | #include "../w1_family.h" |
34 | 33 | ||
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 536d16d78de7..5372cfcbd054 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | 30 | ||
31 | #include "../w1.h" | 31 | #include "../w1.h" |
32 | #include "../w1_io.h" | ||
33 | #include "../w1_int.h" | 32 | #include "../w1_int.h" |
34 | #include "../w1_family.h" | 33 | #include "../w1_family.h" |
35 | 34 | ||
@@ -166,12 +165,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si | |||
166 | u8 rom[9], crc, verdict; | 165 | u8 rom[9], crc, verdict; |
167 | int i, max_trying = 10; | 166 | int i, max_trying = 10; |
168 | 167 | ||
169 | atomic_inc(&sl->refcnt); | 168 | mutex_lock(&sl->master->mutex); |
170 | smp_mb__after_atomic_inc(); | ||
171 | if (down_interruptible(&sl->master->mutex)) { | ||
172 | count = 0; | ||
173 | goto out_dec; | ||
174 | } | ||
175 | 169 | ||
176 | if (off > W1_SLAVE_DATA_SIZE) { | 170 | if (off > W1_SLAVE_DATA_SIZE) { |
177 | count = 0; | 171 | count = 0; |
@@ -234,10 +228,7 @@ static ssize_t w1_therm_read_bin(struct kobject *kobj, char *buf, loff_t off, si | |||
234 | 228 | ||
235 | count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); | 229 | count += sprintf(buf + count, "t=%d\n", w1_convert_temp(rom, sl->family->fid)); |
236 | out: | 230 | out: |
237 | up(&dev->mutex); | 231 | mutex_unlock(&dev->mutex); |
238 | out_dec: | ||
239 | smp_mb__before_atomic_inc(); | ||
240 | atomic_dec(&sl->refcnt); | ||
241 | 232 | ||
242 | return count; | 233 | return count; |
243 | } | 234 | } |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index a698b517e863..de3e9791f80d 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/atomic.h> | 35 | #include <asm/atomic.h> |
36 | 36 | ||
37 | #include "w1.h" | 37 | #include "w1.h" |
38 | #include "w1_io.h" | ||
39 | #include "w1_log.h" | 38 | #include "w1_log.h" |
40 | #include "w1_int.h" | 39 | #include "w1_int.h" |
41 | #include "w1_family.h" | 40 | #include "w1_family.h" |
@@ -55,7 +54,7 @@ module_param_named(control_timeout, w1_control_timeout, int, 0); | |||
55 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); | 54 | module_param_named(max_slave_count, w1_max_slave_count, int, 0); |
56 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); | 55 | module_param_named(slave_ttl, w1_max_slave_ttl, int, 0); |
57 | 56 | ||
58 | DEFINE_SPINLOCK(w1_mlock); | 57 | DEFINE_MUTEX(w1_mlock); |
59 | LIST_HEAD(w1_masters); | 58 | LIST_HEAD(w1_masters); |
60 | 59 | ||
61 | static struct task_struct *w1_control_thread; | 60 | static struct task_struct *w1_control_thread; |
@@ -75,8 +74,6 @@ static void w1_master_release(struct device *dev) | |||
75 | struct w1_master *md = dev_to_w1_master(dev); | 74 | struct w1_master *md = dev_to_w1_master(dev); |
76 | 75 | ||
77 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); | 76 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, md->name); |
78 | |||
79 | dev_fini_netlink(md); | ||
80 | memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); | 77 | memset(md, 0, sizeof(struct w1_master) + sizeof(struct w1_bus_master)); |
81 | kfree(md); | 78 | kfree(md); |
82 | } | 79 | } |
@@ -85,10 +82,10 @@ static void w1_slave_release(struct device *dev) | |||
85 | { | 82 | { |
86 | struct w1_slave *sl = dev_to_w1_slave(dev); | 83 | struct w1_slave *sl = dev_to_w1_slave(dev); |
87 | 84 | ||
88 | dev_dbg(dev, "%s: Releasing %s.\n", __func__, sl->name); | 85 | printk("%s: Releasing %s.\n", __func__, sl->name); |
89 | 86 | ||
90 | while (atomic_read(&sl->refcnt)) { | 87 | while (atomic_read(&sl->refcnt)) { |
91 | dev_dbg(dev, "Waiting for %s to become free: refcnt=%d.\n", | 88 | printk("Waiting for %s to become free: refcnt=%d.\n", |
92 | sl->name, atomic_read(&sl->refcnt)); | 89 | sl->name, atomic_read(&sl->refcnt)); |
93 | if (msleep_interruptible(1000)) | 90 | if (msleep_interruptible(1000)) |
94 | flush_signals(current); | 91 | flush_signals(current); |
@@ -111,7 +108,6 @@ static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, siz | |||
111 | { | 108 | { |
112 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 109 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
113 | 110 | ||
114 | atomic_inc(&sl->refcnt); | ||
115 | if (off > 8) { | 111 | if (off > 8) { |
116 | count = 0; | 112 | count = 0; |
117 | } else { | 113 | } else { |
@@ -120,7 +116,6 @@ static ssize_t w1_slave_read_id(struct kobject *kobj, char *buf, loff_t off, siz | |||
120 | 116 | ||
121 | memcpy(buf, (u8 *)&sl->reg_num, count); | 117 | memcpy(buf, (u8 *)&sl->reg_num, count); |
122 | } | 118 | } |
123 | atomic_dec(&sl->refcnt); | ||
124 | 119 | ||
125 | return count; | 120 | return count; |
126 | } | 121 | } |
@@ -139,7 +134,63 @@ static struct bin_attribute w1_slave_attr_bin_id = { | |||
139 | }; | 134 | }; |
140 | 135 | ||
141 | /* Default family */ | 136 | /* Default family */ |
142 | static struct w1_family w1_default_family; | 137 | |
138 | static ssize_t w1_default_write(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
139 | { | ||
140 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
141 | |||
142 | mutex_lock(&sl->master->mutex); | ||
143 | if (w1_reset_select_slave(sl)) { | ||
144 | count = 0; | ||
145 | goto out_up; | ||
146 | } | ||
147 | |||
148 | w1_write_block(sl->master, buf, count); | ||
149 | |||
150 | out_up: | ||
151 | mutex_unlock(&sl->master->mutex); | ||
152 | return count; | ||
153 | } | ||
154 | |||
155 | static ssize_t w1_default_read(struct kobject *kobj, char *buf, loff_t off, size_t count) | ||
156 | { | ||
157 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | ||
158 | |||
159 | mutex_lock(&sl->master->mutex); | ||
160 | w1_read_block(sl->master, buf, count); | ||
161 | mutex_unlock(&sl->master->mutex); | ||
162 | return count; | ||
163 | } | ||
164 | |||
165 | static struct bin_attribute w1_default_attr = { | ||
166 | .attr = { | ||
167 | .name = "rw", | ||
168 | .mode = S_IRUGO | S_IWUSR, | ||
169 | .owner = THIS_MODULE, | ||
170 | }, | ||
171 | .size = PAGE_SIZE, | ||
172 | .read = w1_default_read, | ||
173 | .write = w1_default_write, | ||
174 | }; | ||
175 | |||
176 | static int w1_default_add_slave(struct w1_slave *sl) | ||
177 | { | ||
178 | return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); | ||
179 | } | ||
180 | |||
181 | static void w1_default_remove_slave(struct w1_slave *sl) | ||
182 | { | ||
183 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); | ||
184 | } | ||
185 | |||
186 | static struct w1_family_ops w1_default_fops = { | ||
187 | .add_slave = w1_default_add_slave, | ||
188 | .remove_slave = w1_default_remove_slave, | ||
189 | }; | ||
190 | |||
191 | static struct w1_family w1_default_family = { | ||
192 | .fops = &w1_default_fops, | ||
193 | }; | ||
143 | 194 | ||
144 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); | 195 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); |
145 | 196 | ||
@@ -183,12 +234,9 @@ static ssize_t w1_master_attribute_show_name(struct device *dev, struct device_a | |||
183 | struct w1_master *md = dev_to_w1_master(dev); | 234 | struct w1_master *md = dev_to_w1_master(dev); |
184 | ssize_t count; | 235 | ssize_t count; |
185 | 236 | ||
186 | if (down_interruptible (&md->mutex)) | 237 | mutex_lock(&md->mutex); |
187 | return -EBUSY; | ||
188 | |||
189 | count = sprintf(buf, "%s\n", md->name); | 238 | count = sprintf(buf, "%s\n", md->name); |
190 | 239 | mutex_unlock(&md->mutex); | |
191 | up(&md->mutex); | ||
192 | 240 | ||
193 | return count; | 241 | return count; |
194 | } | 242 | } |
@@ -199,12 +247,9 @@ static ssize_t w1_master_attribute_store_search(struct device * dev, | |||
199 | { | 247 | { |
200 | struct w1_master *md = dev_to_w1_master(dev); | 248 | struct w1_master *md = dev_to_w1_master(dev); |
201 | 249 | ||
202 | if (down_interruptible (&md->mutex)) | 250 | mutex_lock(&md->mutex); |
203 | return -EBUSY; | ||
204 | |||
205 | md->search_count = simple_strtol(buf, NULL, 0); | 251 | md->search_count = simple_strtol(buf, NULL, 0); |
206 | 252 | mutex_unlock(&md->mutex); | |
207 | up(&md->mutex); | ||
208 | 253 | ||
209 | return count; | 254 | return count; |
210 | } | 255 | } |
@@ -216,12 +261,9 @@ static ssize_t w1_master_attribute_show_search(struct device *dev, | |||
216 | struct w1_master *md = dev_to_w1_master(dev); | 261 | struct w1_master *md = dev_to_w1_master(dev); |
217 | ssize_t count; | 262 | ssize_t count; |
218 | 263 | ||
219 | if (down_interruptible (&md->mutex)) | 264 | mutex_lock(&md->mutex); |
220 | return -EBUSY; | ||
221 | |||
222 | count = sprintf(buf, "%d\n", md->search_count); | 265 | count = sprintf(buf, "%d\n", md->search_count); |
223 | 266 | mutex_unlock(&md->mutex); | |
224 | up(&md->mutex); | ||
225 | 267 | ||
226 | return count; | 268 | return count; |
227 | } | 269 | } |
@@ -231,12 +273,9 @@ static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct devic | |||
231 | struct w1_master *md = dev_to_w1_master(dev); | 273 | struct w1_master *md = dev_to_w1_master(dev); |
232 | ssize_t count; | 274 | ssize_t count; |
233 | 275 | ||
234 | if (down_interruptible(&md->mutex)) | 276 | mutex_lock(&md->mutex); |
235 | return -EBUSY; | ||
236 | |||
237 | count = sprintf(buf, "0x%p\n", md->bus_master); | 277 | count = sprintf(buf, "0x%p\n", md->bus_master); |
238 | 278 | mutex_unlock(&md->mutex); | |
239 | up(&md->mutex); | ||
240 | return count; | 279 | return count; |
241 | } | 280 | } |
242 | 281 | ||
@@ -252,12 +291,9 @@ static ssize_t w1_master_attribute_show_max_slave_count(struct device *dev, stru | |||
252 | struct w1_master *md = dev_to_w1_master(dev); | 291 | struct w1_master *md = dev_to_w1_master(dev); |
253 | ssize_t count; | 292 | ssize_t count; |
254 | 293 | ||
255 | if (down_interruptible(&md->mutex)) | 294 | mutex_lock(&md->mutex); |
256 | return -EBUSY; | ||
257 | |||
258 | count = sprintf(buf, "%d\n", md->max_slave_count); | 295 | count = sprintf(buf, "%d\n", md->max_slave_count); |
259 | 296 | mutex_unlock(&md->mutex); | |
260 | up(&md->mutex); | ||
261 | return count; | 297 | return count; |
262 | } | 298 | } |
263 | 299 | ||
@@ -266,12 +302,9 @@ static ssize_t w1_master_attribute_show_attempts(struct device *dev, struct devi | |||
266 | struct w1_master *md = dev_to_w1_master(dev); | 302 | struct w1_master *md = dev_to_w1_master(dev); |
267 | ssize_t count; | 303 | ssize_t count; |
268 | 304 | ||
269 | if (down_interruptible(&md->mutex)) | 305 | mutex_lock(&md->mutex); |
270 | return -EBUSY; | ||
271 | |||
272 | count = sprintf(buf, "%lu\n", md->attempts); | 306 | count = sprintf(buf, "%lu\n", md->attempts); |
273 | 307 | mutex_unlock(&md->mutex); | |
274 | up(&md->mutex); | ||
275 | return count; | 308 | return count; |
276 | } | 309 | } |
277 | 310 | ||
@@ -280,12 +313,9 @@ static ssize_t w1_master_attribute_show_slave_count(struct device *dev, struct d | |||
280 | struct w1_master *md = dev_to_w1_master(dev); | 313 | struct w1_master *md = dev_to_w1_master(dev); |
281 | ssize_t count; | 314 | ssize_t count; |
282 | 315 | ||
283 | if (down_interruptible(&md->mutex)) | 316 | mutex_lock(&md->mutex); |
284 | return -EBUSY; | ||
285 | |||
286 | count = sprintf(buf, "%d\n", md->slave_count); | 317 | count = sprintf(buf, "%d\n", md->slave_count); |
287 | 318 | mutex_unlock(&md->mutex); | |
288 | up(&md->mutex); | ||
289 | return count; | 319 | return count; |
290 | } | 320 | } |
291 | 321 | ||
@@ -294,8 +324,7 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device | |||
294 | struct w1_master *md = dev_to_w1_master(dev); | 324 | struct w1_master *md = dev_to_w1_master(dev); |
295 | int c = PAGE_SIZE; | 325 | int c = PAGE_SIZE; |
296 | 326 | ||
297 | if (down_interruptible(&md->mutex)) | 327 | mutex_lock(&md->mutex); |
298 | return -EBUSY; | ||
299 | 328 | ||
300 | if (md->slave_count == 0) | 329 | if (md->slave_count == 0) |
301 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); | 330 | c -= snprintf(buf + PAGE_SIZE - c, c, "not found.\n"); |
@@ -310,7 +339,7 @@ static ssize_t w1_master_attribute_show_slaves(struct device *dev, struct device | |||
310 | } | 339 | } |
311 | } | 340 | } |
312 | 341 | ||
313 | up(&md->mutex); | 342 | mutex_unlock(&md->mutex); |
314 | 343 | ||
315 | return PAGE_SIZE - c; | 344 | return PAGE_SIZE - c; |
316 | } | 345 | } |
@@ -362,7 +391,8 @@ static void w1_destroy_master_attributes(struct w1_master *master) | |||
362 | } | 391 | } |
363 | 392 | ||
364 | #ifdef CONFIG_HOTPLUG | 393 | #ifdef CONFIG_HOTPLUG |
365 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 394 | static int w1_uevent(struct device *dev, char **envp, int num_envp, |
395 | char *buffer, int buffer_size) | ||
366 | { | 396 | { |
367 | struct w1_master *md = NULL; | 397 | struct w1_master *md = NULL; |
368 | struct w1_slave *sl = NULL; | 398 | struct w1_slave *sl = NULL; |
@@ -382,7 +412,8 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer | |||
382 | return -EINVAL; | 412 | return -EINVAL; |
383 | } | 413 | } |
384 | 414 | ||
385 | dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", event_owner, name, dev->bus_id); | 415 | dev_dbg(dev, "Hotplug event for %s %s, bus_id=%s.\n", |
416 | event_owner, name, dev->bus_id); | ||
386 | 417 | ||
387 | if (dev->driver != &w1_slave_driver || !sl) | 418 | if (dev->driver != &w1_slave_driver || !sl) |
388 | return 0; | 419 | return 0; |
@@ -401,7 +432,8 @@ static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer | |||
401 | return 0; | 432 | return 0; |
402 | }; | 433 | }; |
403 | #else | 434 | #else |
404 | static int w1_uevent(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size) | 435 | static int w1_uevent(struct device *dev, char **envp, int num_envp, |
436 | char *buffer, int buffer_size) | ||
405 | { | 437 | { |
406 | return 0; | 438 | return 0; |
407 | } | 439 | } |
@@ -425,7 +457,8 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
425 | (unsigned int) sl->reg_num.family, | 457 | (unsigned int) sl->reg_num.family, |
426 | (unsigned long long) sl->reg_num.id); | 458 | (unsigned long long) sl->reg_num.id); |
427 | 459 | ||
428 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, &sl->dev.bus_id[0]); | 460 | dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__, |
461 | &sl->dev.bus_id[0]); | ||
429 | 462 | ||
430 | err = device_register(&sl->dev); | 463 | err = device_register(&sl->dev); |
431 | if (err < 0) { | 464 | if (err < 0) { |
@@ -496,6 +529,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
496 | sl->master = dev; | 529 | sl->master = dev; |
497 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | 530 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
498 | 531 | ||
532 | memset(&msg, 0, sizeof(msg)); | ||
499 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); | 533 | memcpy(&sl->reg_num, rn, sizeof(sl->reg_num)); |
500 | atomic_set(&sl->refcnt, 0); | 534 | atomic_set(&sl->refcnt, 0); |
501 | init_completion(&sl->released); | 535 | init_completion(&sl->released); |
@@ -526,7 +560,7 @@ static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | |||
526 | sl->ttl = dev->slave_ttl; | 560 | sl->ttl = dev->slave_ttl; |
527 | dev->slave_count++; | 561 | dev->slave_count++; |
528 | 562 | ||
529 | memcpy(&msg.id.id, rn, sizeof(msg.id.id)); | 563 | memcpy(msg.id.id, rn, sizeof(msg.id)); |
530 | msg.type = W1_SLAVE_ADD; | 564 | msg.type = W1_SLAVE_ADD; |
531 | w1_netlink_send(dev, &msg); | 565 | w1_netlink_send(dev, &msg); |
532 | 566 | ||
@@ -544,7 +578,8 @@ static void w1_slave_detach(struct w1_slave *sl) | |||
544 | if (sl->family->fops && sl->family->fops->remove_slave) | 578 | if (sl->family->fops && sl->family->fops->remove_slave) |
545 | sl->family->fops->remove_slave(sl); | 579 | sl->family->fops->remove_slave(sl); |
546 | 580 | ||
547 | memcpy(&msg.id.id, &sl->reg_num, sizeof(msg.id.id)); | 581 | memset(&msg, 0, sizeof(msg)); |
582 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); | ||
548 | msg.type = W1_SLAVE_REMOVE; | 583 | msg.type = W1_SLAVE_REMOVE; |
549 | w1_netlink_send(sl->master, &msg); | 584 | w1_netlink_send(sl->master, &msg); |
550 | 585 | ||
@@ -561,7 +596,7 @@ static struct w1_master *w1_search_master(void *data) | |||
561 | struct w1_master *dev; | 596 | struct w1_master *dev; |
562 | int found = 0; | 597 | int found = 0; |
563 | 598 | ||
564 | spin_lock_bh(&w1_mlock); | 599 | mutex_lock(&w1_mlock); |
565 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 600 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
566 | if (dev->bus_master->data == data) { | 601 | if (dev->bus_master->data == data) { |
567 | found = 1; | 602 | found = 1; |
@@ -569,22 +604,69 @@ static struct w1_master *w1_search_master(void *data) | |||
569 | break; | 604 | break; |
570 | } | 605 | } |
571 | } | 606 | } |
572 | spin_unlock_bh(&w1_mlock); | 607 | mutex_unlock(&w1_mlock); |
608 | |||
609 | return (found)?dev:NULL; | ||
610 | } | ||
611 | |||
612 | struct w1_master *w1_search_master_id(u32 id) | ||
613 | { | ||
614 | struct w1_master *dev; | ||
615 | int found = 0; | ||
616 | |||
617 | mutex_lock(&w1_mlock); | ||
618 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | ||
619 | if (dev->id == id) { | ||
620 | found = 1; | ||
621 | atomic_inc(&dev->refcnt); | ||
622 | break; | ||
623 | } | ||
624 | } | ||
625 | mutex_unlock(&w1_mlock); | ||
573 | 626 | ||
574 | return (found)?dev:NULL; | 627 | return (found)?dev:NULL; |
575 | } | 628 | } |
576 | 629 | ||
630 | struct w1_slave *w1_search_slave(struct w1_reg_num *id) | ||
631 | { | ||
632 | struct w1_master *dev; | ||
633 | struct w1_slave *sl = NULL; | ||
634 | int found = 0; | ||
635 | |||
636 | mutex_lock(&w1_mlock); | ||
637 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | ||
638 | mutex_lock(&dev->mutex); | ||
639 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) { | ||
640 | if (sl->reg_num.family == id->family && | ||
641 | sl->reg_num.id == id->id && | ||
642 | sl->reg_num.crc == id->crc) { | ||
643 | found = 1; | ||
644 | atomic_inc(&dev->refcnt); | ||
645 | atomic_inc(&sl->refcnt); | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | mutex_unlock(&dev->mutex); | ||
650 | |||
651 | if (found) | ||
652 | break; | ||
653 | } | ||
654 | mutex_unlock(&w1_mlock); | ||
655 | |||
656 | return (found)?sl:NULL; | ||
657 | } | ||
658 | |||
577 | void w1_reconnect_slaves(struct w1_family *f) | 659 | void w1_reconnect_slaves(struct w1_family *f) |
578 | { | 660 | { |
579 | struct w1_master *dev; | 661 | struct w1_master *dev; |
580 | 662 | ||
581 | spin_lock_bh(&w1_mlock); | 663 | mutex_lock(&w1_mlock); |
582 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { | 664 | list_for_each_entry(dev, &w1_masters, w1_master_entry) { |
583 | dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", | 665 | dev_dbg(&dev->dev, "Reconnecting slaves in %s into new family %02x.\n", |
584 | dev->name, f->fid); | 666 | dev->name, f->fid); |
585 | set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); | 667 | set_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); |
586 | } | 668 | } |
587 | spin_unlock_bh(&w1_mlock); | 669 | mutex_unlock(&w1_mlock); |
588 | } | 670 | } |
589 | 671 | ||
590 | static void w1_slave_found(void *data, u64 rn) | 672 | static void w1_slave_found(void *data, u64 rn) |
@@ -646,7 +728,7 @@ static void w1_slave_found(void *data, u64 rn) | |||
646 | * @dev The master device to search | 728 | * @dev The master device to search |
647 | * @cb Function to call when a device is found | 729 | * @cb Function to call when a device is found |
648 | */ | 730 | */ |
649 | void w1_search(struct w1_master *dev, w1_slave_found_callback cb) | 731 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) |
650 | { | 732 | { |
651 | u64 last_rn, rn, tmp64; | 733 | u64 last_rn, rn, tmp64; |
652 | int i, slave_count = 0; | 734 | int i, slave_count = 0; |
@@ -677,7 +759,7 @@ void w1_search(struct w1_master *dev, w1_slave_found_callback cb) | |||
677 | } | 759 | } |
678 | 760 | ||
679 | /* Start the search */ | 761 | /* Start the search */ |
680 | w1_write_8(dev, W1_SEARCH); | 762 | w1_write_8(dev, search_type); |
681 | for (i = 0; i < 64; ++i) { | 763 | for (i = 0; i < 64; ++i) { |
682 | /* Determine the direction/search bit */ | 764 | /* Determine the direction/search bit */ |
683 | if (i == desc_bit) | 765 | if (i == desc_bit) |
@@ -739,23 +821,23 @@ static int w1_control(void *data) | |||
739 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | 821 | if (kthread_should_stop() || test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
740 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 822 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); |
741 | 823 | ||
742 | spin_lock(&w1_mlock); | 824 | mutex_lock(&w1_mlock); |
743 | list_del(&dev->w1_master_entry); | 825 | list_del(&dev->w1_master_entry); |
744 | spin_unlock(&w1_mlock); | 826 | mutex_unlock(&w1_mlock); |
745 | 827 | ||
746 | down(&dev->mutex); | 828 | mutex_lock(&dev->mutex); |
747 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 829 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
748 | w1_slave_detach(sl); | 830 | w1_slave_detach(sl); |
749 | } | 831 | } |
750 | w1_destroy_master_attributes(dev); | 832 | w1_destroy_master_attributes(dev); |
751 | up(&dev->mutex); | 833 | mutex_unlock(&dev->mutex); |
752 | atomic_dec(&dev->refcnt); | 834 | atomic_dec(&dev->refcnt); |
753 | continue; | 835 | continue; |
754 | } | 836 | } |
755 | 837 | ||
756 | if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { | 838 | if (test_bit(W1_MASTER_NEED_RECONNECT, &dev->flags)) { |
757 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); | 839 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s.\n", dev->name); |
758 | down(&dev->mutex); | 840 | mutex_lock(&dev->mutex); |
759 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | 841 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { |
760 | if (sl->family->fid == W1_FAMILY_DEFAULT) { | 842 | if (sl->family->fid == W1_FAMILY_DEFAULT) { |
761 | struct w1_reg_num rn; | 843 | struct w1_reg_num rn; |
@@ -768,7 +850,7 @@ static int w1_control(void *data) | |||
768 | } | 850 | } |
769 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name); | 851 | dev_dbg(&dev->dev, "Reconnecting slaves in device %s has been finished.\n", dev->name); |
770 | clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); | 852 | clear_bit(W1_MASTER_NEED_RECONNECT, &dev->flags); |
771 | up(&dev->mutex); | 853 | mutex_unlock(&dev->mutex); |
772 | } | 854 | } |
773 | } | 855 | } |
774 | } | 856 | } |
@@ -776,10 +858,31 @@ static int w1_control(void *data) | |||
776 | return 0; | 858 | return 0; |
777 | } | 859 | } |
778 | 860 | ||
861 | void w1_search_process(struct w1_master *dev, u8 search_type) | ||
862 | { | ||
863 | struct w1_slave *sl, *sln; | ||
864 | |||
865 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) | ||
866 | clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | ||
867 | |||
868 | w1_search_devices(dev, search_type, w1_slave_found); | ||
869 | |||
870 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | ||
871 | if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { | ||
872 | w1_slave_detach(sl); | ||
873 | |||
874 | dev->slave_count--; | ||
875 | } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) | ||
876 | sl->ttl = dev->slave_ttl; | ||
877 | } | ||
878 | |||
879 | if (dev->search_count > 0) | ||
880 | dev->search_count--; | ||
881 | } | ||
882 | |||
779 | int w1_process(void *data) | 883 | int w1_process(void *data) |
780 | { | 884 | { |
781 | struct w1_master *dev = (struct w1_master *) data; | 885 | struct w1_master *dev = (struct w1_master *) data; |
782 | struct w1_slave *sl, *sln; | ||
783 | 886 | ||
784 | while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { | 887 | while (!kthread_should_stop() && !test_bit(W1_MASTER_NEED_EXIT, &dev->flags)) { |
785 | try_to_freeze(); | 888 | try_to_freeze(); |
@@ -794,27 +897,9 @@ int w1_process(void *data) | |||
794 | if (dev->search_count == 0) | 897 | if (dev->search_count == 0) |
795 | continue; | 898 | continue; |
796 | 899 | ||
797 | if (down_interruptible(&dev->mutex)) | 900 | mutex_lock(&dev->mutex); |
798 | continue; | 901 | w1_search_process(dev, W1_SEARCH); |
799 | 902 | mutex_unlock(&dev->mutex); | |
800 | list_for_each_entry(sl, &dev->slist, w1_slave_entry) | ||
801 | clear_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | ||
802 | |||
803 | w1_search_devices(dev, w1_slave_found); | ||
804 | |||
805 | list_for_each_entry_safe(sl, sln, &dev->slist, w1_slave_entry) { | ||
806 | if (!test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags) && !--sl->ttl) { | ||
807 | w1_slave_detach(sl); | ||
808 | |||
809 | dev->slave_count--; | ||
810 | } else if (test_bit(W1_SLAVE_ACTIVE, (unsigned long *)&sl->flags)) | ||
811 | sl->ttl = dev->slave_ttl; | ||
812 | } | ||
813 | |||
814 | if (dev->search_count > 0) | ||
815 | dev->search_count--; | ||
816 | |||
817 | up(&dev->mutex); | ||
818 | } | 903 | } |
819 | 904 | ||
820 | atomic_dec(&dev->refcnt); | 905 | atomic_dec(&dev->refcnt); |
@@ -828,6 +913,8 @@ static int w1_init(void) | |||
828 | 913 | ||
829 | printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); | 914 | printk(KERN_INFO "Driver for 1-wire Dallas network protocol.\n"); |
830 | 915 | ||
916 | w1_init_netlink(); | ||
917 | |||
831 | retval = bus_register(&w1_bus_type); | 918 | retval = bus_register(&w1_bus_type); |
832 | if (retval) { | 919 | if (retval) { |
833 | printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); | 920 | printk(KERN_ERR "Failed to register bus. err=%d.\n", retval); |
@@ -880,6 +967,8 @@ static void w1_fini(void) | |||
880 | list_for_each_entry(dev, &w1_masters, w1_master_entry) | 967 | list_for_each_entry(dev, &w1_masters, w1_master_entry) |
881 | __w1_remove_master_device(dev); | 968 | __w1_remove_master_device(dev); |
882 | 969 | ||
970 | w1_fini_netlink(); | ||
971 | |||
883 | kthread_stop(w1_control_thread); | 972 | kthread_stop(w1_control_thread); |
884 | 973 | ||
885 | driver_unregister(&w1_slave_driver); | 974 | driver_unregister(&w1_slave_driver); |
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h index 56980505e6c4..f1df5343f4ad 100644 --- a/drivers/w1/w1.h +++ b/drivers/w1/w1.h | |||
@@ -41,10 +41,7 @@ struct w1_reg_num | |||
41 | 41 | ||
42 | #include <linux/completion.h> | 42 | #include <linux/completion.h> |
43 | #include <linux/device.h> | 43 | #include <linux/device.h> |
44 | 44 | #include <linux/mutex.h> | |
45 | #include <net/sock.h> | ||
46 | |||
47 | #include <asm/semaphore.h> | ||
48 | 45 | ||
49 | #include "w1_family.h" | 46 | #include "w1_family.h" |
50 | 47 | ||
@@ -52,7 +49,7 @@ struct w1_reg_num | |||
52 | #define W1_SLAVE_DATA_SIZE 128 | 49 | #define W1_SLAVE_DATA_SIZE 128 |
53 | 50 | ||
54 | #define W1_SEARCH 0xF0 | 51 | #define W1_SEARCH 0xF0 |
55 | #define W1_CONDITIONAL_SEARCH 0xEC | 52 | #define W1_ALARM_SEARCH 0xEC |
56 | #define W1_CONVERT_TEMP 0x44 | 53 | #define W1_CONVERT_TEMP 0x44 |
57 | #define W1_SKIP_ROM 0xCC | 54 | #define W1_SKIP_ROM 0xCC |
58 | #define W1_READ_SCRATCHPAD 0xBE | 55 | #define W1_READ_SCRATCHPAD 0xBE |
@@ -60,7 +57,7 @@ struct w1_reg_num | |||
60 | #define W1_READ_PSUPPLY 0xB4 | 57 | #define W1_READ_PSUPPLY 0xB4 |
61 | #define W1_MATCH_ROM 0x55 | 58 | #define W1_MATCH_ROM 0x55 |
62 | 59 | ||
63 | #define W1_SLAVE_ACTIVE (1<<0) | 60 | #define W1_SLAVE_ACTIVE 0 |
64 | 61 | ||
65 | struct w1_slave | 62 | struct w1_slave |
66 | { | 63 | { |
@@ -145,8 +142,8 @@ struct w1_bus_master | |||
145 | */ | 142 | */ |
146 | u8 (*reset_bus)(void *); | 143 | u8 (*reset_bus)(void *); |
147 | 144 | ||
148 | /** Really nice hardware can handles the ROM searches */ | 145 | /** Really nice hardware can handles the different types of ROM search */ |
149 | void (*search)(void *, w1_slave_found_callback); | 146 | void (*search)(void *, u8, w1_slave_found_callback); |
150 | }; | 147 | }; |
151 | 148 | ||
152 | #define W1_MASTER_NEED_EXIT 0 | 149 | #define W1_MASTER_NEED_EXIT 0 |
@@ -173,19 +170,30 @@ struct w1_master | |||
173 | long flags; | 170 | long flags; |
174 | 171 | ||
175 | struct task_struct *thread; | 172 | struct task_struct *thread; |
176 | struct semaphore mutex; | 173 | struct mutex mutex; |
177 | 174 | ||
178 | struct device_driver *driver; | 175 | struct device_driver *driver; |
179 | struct device dev; | 176 | struct device dev; |
180 | 177 | ||
181 | struct w1_bus_master *bus_master; | 178 | struct w1_bus_master *bus_master; |
182 | 179 | ||
183 | u32 seq, groups; | 180 | u32 seq; |
184 | struct sock *nls; | ||
185 | }; | 181 | }; |
186 | 182 | ||
187 | int w1_create_master_attributes(struct w1_master *); | 183 | int w1_create_master_attributes(struct w1_master *); |
188 | void w1_search(struct w1_master *dev, w1_slave_found_callback cb); | 184 | void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); |
185 | void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb); | ||
186 | struct w1_slave *w1_search_slave(struct w1_reg_num *id); | ||
187 | void w1_search_process(struct w1_master *dev, u8 search_type); | ||
188 | struct w1_master *w1_search_master_id(u32 id); | ||
189 | |||
190 | u8 w1_triplet(struct w1_master *dev, int bdir); | ||
191 | void w1_write_8(struct w1_master *, u8); | ||
192 | int w1_reset_bus(struct w1_master *); | ||
193 | u8 w1_calc_crc8(u8 *, int); | ||
194 | void w1_write_block(struct w1_master *, const u8 *, int); | ||
195 | u8 w1_read_block(struct w1_master *, u8 *, int); | ||
196 | int w1_reset_select_slave(struct w1_slave *sl); | ||
189 | 197 | ||
190 | static inline struct w1_slave* dev_to_w1_slave(struct device *dev) | 198 | static inline struct w1_slave* dev_to_w1_slave(struct device *dev) |
191 | { | 199 | { |
@@ -202,15 +210,14 @@ static inline struct w1_master* dev_to_w1_master(struct device *dev) | |||
202 | return container_of(dev, struct w1_master, dev); | 210 | return container_of(dev, struct w1_master, dev); |
203 | } | 211 | } |
204 | 212 | ||
213 | extern struct device_driver w1_master_driver; | ||
214 | extern struct device w1_master_device; | ||
205 | extern int w1_max_slave_count; | 215 | extern int w1_max_slave_count; |
206 | extern int w1_max_slave_ttl; | 216 | extern int w1_max_slave_ttl; |
207 | extern spinlock_t w1_mlock; | ||
208 | extern struct list_head w1_masters; | 217 | extern struct list_head w1_masters; |
209 | extern struct device_driver w1_master_driver; | 218 | extern struct mutex w1_mlock; |
210 | extern struct device w1_master_device; | ||
211 | 219 | ||
212 | int w1_process(void *data); | 220 | extern int w1_process(void *); |
213 | void w1_reconnect_slaves(struct w1_family *f); | ||
214 | 221 | ||
215 | #endif /* __KERNEL__ */ | 222 | #endif /* __KERNEL__ */ |
216 | 223 | ||
diff --git a/drivers/w1/w1_family.c b/drivers/w1/w1_family.c index 0e32c114f906..a3c95bd6890a 100644 --- a/drivers/w1/w1_family.c +++ b/drivers/w1/w1_family.c | |||
@@ -107,6 +107,12 @@ struct w1_family * w1_family_registered(u8 fid) | |||
107 | return (ret) ? f : NULL; | 107 | return (ret) ? f : NULL; |
108 | } | 108 | } |
109 | 109 | ||
110 | static void __w1_family_put(struct w1_family *f) | ||
111 | { | ||
112 | if (atomic_dec_and_test(&f->refcnt)) | ||
113 | f->need_exit = 1; | ||
114 | } | ||
115 | |||
110 | void w1_family_put(struct w1_family *f) | 116 | void w1_family_put(struct w1_family *f) |
111 | { | 117 | { |
112 | spin_lock(&w1_flock); | 118 | spin_lock(&w1_flock); |
@@ -114,19 +120,14 @@ void w1_family_put(struct w1_family *f) | |||
114 | spin_unlock(&w1_flock); | 120 | spin_unlock(&w1_flock); |
115 | } | 121 | } |
116 | 122 | ||
117 | void __w1_family_put(struct w1_family *f) | 123 | #if 0 |
118 | { | ||
119 | if (atomic_dec_and_test(&f->refcnt)) | ||
120 | f->need_exit = 1; | ||
121 | } | ||
122 | |||
123 | void w1_family_get(struct w1_family *f) | 124 | void w1_family_get(struct w1_family *f) |
124 | { | 125 | { |
125 | spin_lock(&w1_flock); | 126 | spin_lock(&w1_flock); |
126 | __w1_family_get(f); | 127 | __w1_family_get(f); |
127 | spin_unlock(&w1_flock); | 128 | spin_unlock(&w1_flock); |
128 | |||
129 | } | 129 | } |
130 | #endif /* 0 */ | ||
130 | 131 | ||
131 | void __w1_family_get(struct w1_family *f) | 132 | void __w1_family_get(struct w1_family *f) |
132 | { | 133 | { |
@@ -135,8 +136,5 @@ void __w1_family_get(struct w1_family *f) | |||
135 | smp_mb__after_atomic_inc(); | 136 | smp_mb__after_atomic_inc(); |
136 | } | 137 | } |
137 | 138 | ||
138 | EXPORT_SYMBOL(w1_family_get); | ||
139 | EXPORT_SYMBOL(w1_family_put); | ||
140 | EXPORT_SYMBOL(w1_family_registered); | ||
141 | EXPORT_SYMBOL(w1_unregister_family); | 139 | EXPORT_SYMBOL(w1_unregister_family); |
142 | EXPORT_SYMBOL(w1_register_family); | 140 | EXPORT_SYMBOL(w1_register_family); |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 2ca0489c716a..1e2ac40c2c14 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -57,12 +57,11 @@ struct w1_family | |||
57 | 57 | ||
58 | extern spinlock_t w1_flock; | 58 | extern spinlock_t w1_flock; |
59 | 59 | ||
60 | void w1_family_get(struct w1_family *); | ||
61 | void w1_family_put(struct w1_family *); | 60 | void w1_family_put(struct w1_family *); |
62 | void __w1_family_get(struct w1_family *); | 61 | void __w1_family_get(struct w1_family *); |
63 | void __w1_family_put(struct w1_family *); | ||
64 | struct w1_family * w1_family_registered(u8); | 62 | struct w1_family * w1_family_registered(u8); |
65 | void w1_unregister_family(struct w1_family *); | 63 | void w1_unregister_family(struct w1_family *); |
66 | int w1_register_family(struct w1_family *); | 64 | int w1_register_family(struct w1_family *); |
65 | void w1_reconnect_slaves(struct w1_family *f); | ||
67 | 66 | ||
68 | #endif /* __W1_FAMILY_H */ | 67 | #endif /* __W1_FAMILY_H */ |
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 68565aacec7b..357a2e0f637a 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c | |||
@@ -65,7 +65,7 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
65 | atomic_set(&dev->refcnt, 2); | 65 | atomic_set(&dev->refcnt, 2); |
66 | 66 | ||
67 | INIT_LIST_HEAD(&dev->slist); | 67 | INIT_LIST_HEAD(&dev->slist); |
68 | init_MUTEX(&dev->mutex); | 68 | mutex_init(&dev->mutex); |
69 | 69 | ||
70 | memcpy(&dev->dev, device, sizeof(struct device)); | 70 | memcpy(&dev->dev, device, sizeof(struct device)); |
71 | snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), | 71 | snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), |
@@ -74,16 +74,11 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl, | |||
74 | 74 | ||
75 | dev->driver = driver; | 75 | dev->driver = driver; |
76 | 76 | ||
77 | dev->groups = 1; | ||
78 | dev->seq = 1; | 77 | dev->seq = 1; |
79 | dev_init_netlink(dev); | ||
80 | 78 | ||
81 | err = device_register(&dev->dev); | 79 | err = device_register(&dev->dev); |
82 | if (err) { | 80 | if (err) { |
83 | printk(KERN_ERR "Failed to register master device. err=%d\n", err); | 81 | printk(KERN_ERR "Failed to register master device. err=%d\n", err); |
84 | |||
85 | dev_fini_netlink(dev); | ||
86 | |||
87 | memset(dev, 0, sizeof(struct w1_master)); | 82 | memset(dev, 0, sizeof(struct w1_master)); |
88 | kfree(dev); | 83 | kfree(dev); |
89 | dev = NULL; | 84 | dev = NULL; |
@@ -131,12 +126,12 @@ int w1_add_master_device(struct w1_bus_master *master) | |||
131 | 126 | ||
132 | dev->initialized = 1; | 127 | dev->initialized = 1; |
133 | 128 | ||
134 | spin_lock(&w1_mlock); | 129 | mutex_lock(&w1_mlock); |
135 | list_add(&dev->w1_master_entry, &w1_masters); | 130 | list_add(&dev->w1_master_entry, &w1_masters); |
136 | spin_unlock(&w1_mlock); | 131 | mutex_unlock(&w1_mlock); |
137 | 132 | ||
133 | memset(&msg, 0, sizeof(msg)); | ||
138 | msg.id.mst.id = dev->id; | 134 | msg.id.mst.id = dev->id; |
139 | msg.id.mst.pid = dev->thread->pid; | ||
140 | msg.type = W1_MASTER_ADD; | 135 | msg.type = W1_MASTER_ADD; |
141 | w1_netlink_send(dev, &msg); | 136 | w1_netlink_send(dev, &msg); |
142 | 137 | ||
@@ -153,7 +148,6 @@ err_out_free_dev: | |||
153 | void __w1_remove_master_device(struct w1_master *dev) | 148 | void __w1_remove_master_device(struct w1_master *dev) |
154 | { | 149 | { |
155 | struct w1_netlink_msg msg; | 150 | struct w1_netlink_msg msg; |
156 | pid_t pid = dev->thread->pid; | ||
157 | 151 | ||
158 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); | 152 | set_bit(W1_MASTER_NEED_EXIT, &dev->flags); |
159 | kthread_stop(dev->thread); | 153 | kthread_stop(dev->thread); |
@@ -166,8 +160,8 @@ void __w1_remove_master_device(struct w1_master *dev) | |||
166 | flush_signals(current); | 160 | flush_signals(current); |
167 | } | 161 | } |
168 | 162 | ||
163 | memset(&msg, 0, sizeof(msg)); | ||
169 | msg.id.mst.id = dev->id; | 164 | msg.id.mst.id = dev->id; |
170 | msg.id.mst.pid = pid; | ||
171 | msg.type = W1_MASTER_REMOVE; | 165 | msg.type = W1_MASTER_REMOVE; |
172 | w1_netlink_send(dev, &msg); | 166 | w1_netlink_send(dev, &msg); |
173 | 167 | ||
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c index f7f7e8bec30e..30b6fbf83bd4 100644 --- a/drivers/w1/w1_io.c +++ b/drivers/w1/w1_io.c | |||
@@ -23,10 +23,10 @@ | |||
23 | 23 | ||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/module.h> | ||
26 | 27 | ||
27 | #include "w1.h" | 28 | #include "w1.h" |
28 | #include "w1_log.h" | 29 | #include "w1_log.h" |
29 | #include "w1_io.h" | ||
30 | 30 | ||
31 | static int w1_delay_parm = 1; | 31 | static int w1_delay_parm = 1; |
32 | module_param_named(delay_coef, w1_delay_parm, int, 0); | 32 | module_param_named(delay_coef, w1_delay_parm, int, 0); |
@@ -50,7 +50,7 @@ static u8 w1_crc8_table[] = { | |||
50 | 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 | 50 | 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 |
51 | }; | 51 | }; |
52 | 52 | ||
53 | void w1_delay(unsigned long tm) | 53 | static void w1_delay(unsigned long tm) |
54 | { | 54 | { |
55 | udelay(tm * w1_delay_parm); | 55 | udelay(tm * w1_delay_parm); |
56 | } | 56 | } |
@@ -61,7 +61,7 @@ static u8 w1_read_bit(struct w1_master *dev); | |||
61 | /** | 61 | /** |
62 | * Generates a write-0 or write-1 cycle and samples the level. | 62 | * Generates a write-0 or write-1 cycle and samples the level. |
63 | */ | 63 | */ |
64 | u8 w1_touch_bit(struct w1_master *dev, int bit) | 64 | static u8 w1_touch_bit(struct w1_master *dev, int bit) |
65 | { | 65 | { |
66 | if (dev->bus_master->touch_bit) | 66 | if (dev->bus_master->touch_bit) |
67 | return dev->bus_master->touch_bit(dev->bus_master->data, bit); | 67 | return dev->bus_master->touch_bit(dev->bus_master->data, bit); |
@@ -108,6 +108,7 @@ void w1_write_8(struct w1_master *dev, u8 byte) | |||
108 | for (i = 0; i < 8; ++i) | 108 | for (i = 0; i < 8; ++i) |
109 | w1_touch_bit(dev, (byte >> i) & 0x1); | 109 | w1_touch_bit(dev, (byte >> i) & 0x1); |
110 | } | 110 | } |
111 | EXPORT_SYMBOL_GPL(w1_write_8); | ||
111 | 112 | ||
112 | 113 | ||
113 | /** | 114 | /** |
@@ -176,7 +177,7 @@ u8 w1_triplet(struct w1_master *dev, int bdir) | |||
176 | * @param dev the master device | 177 | * @param dev the master device |
177 | * @return the byte read | 178 | * @return the byte read |
178 | */ | 179 | */ |
179 | u8 w1_read_8(struct w1_master * dev) | 180 | static u8 w1_read_8(struct w1_master * dev) |
180 | { | 181 | { |
181 | int i; | 182 | int i; |
182 | u8 res = 0; | 183 | u8 res = 0; |
@@ -208,6 +209,7 @@ void w1_write_block(struct w1_master *dev, const u8 *buf, int len) | |||
208 | for (i = 0; i < len; ++i) | 209 | for (i = 0; i < len; ++i) |
209 | w1_write_8(dev, buf[i]); | 210 | w1_write_8(dev, buf[i]); |
210 | } | 211 | } |
212 | EXPORT_SYMBOL_GPL(w1_write_block); | ||
211 | 213 | ||
212 | /** | 214 | /** |
213 | * Reads a series of bytes. | 215 | * Reads a series of bytes. |
@@ -232,6 +234,7 @@ u8 w1_read_block(struct w1_master *dev, u8 *buf, int len) | |||
232 | 234 | ||
233 | return ret; | 235 | return ret; |
234 | } | 236 | } |
237 | EXPORT_SYMBOL_GPL(w1_read_block); | ||
235 | 238 | ||
236 | /** | 239 | /** |
237 | * Issues a reset bus sequence. | 240 | * Issues a reset bus sequence. |
@@ -257,6 +260,7 @@ int w1_reset_bus(struct w1_master *dev) | |||
257 | 260 | ||
258 | return result; | 261 | return result; |
259 | } | 262 | } |
263 | EXPORT_SYMBOL_GPL(w1_reset_bus); | ||
260 | 264 | ||
261 | u8 w1_calc_crc8(u8 * data, int len) | 265 | u8 w1_calc_crc8(u8 * data, int len) |
262 | { | 266 | { |
@@ -267,14 +271,15 @@ u8 w1_calc_crc8(u8 * data, int len) | |||
267 | 271 | ||
268 | return crc; | 272 | return crc; |
269 | } | 273 | } |
274 | EXPORT_SYMBOL_GPL(w1_calc_crc8); | ||
270 | 275 | ||
271 | void w1_search_devices(struct w1_master *dev, w1_slave_found_callback cb) | 276 | void w1_search_devices(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb) |
272 | { | 277 | { |
273 | dev->attempts++; | 278 | dev->attempts++; |
274 | if (dev->bus_master->search) | 279 | if (dev->bus_master->search) |
275 | dev->bus_master->search(dev->bus_master->data, cb); | 280 | dev->bus_master->search(dev->bus_master->data, search_type, cb); |
276 | else | 281 | else |
277 | w1_search(dev, cb); | 282 | w1_search(dev, search_type, cb); |
278 | } | 283 | } |
279 | 284 | ||
280 | /** | 285 | /** |
@@ -299,14 +304,4 @@ int w1_reset_select_slave(struct w1_slave *sl) | |||
299 | } | 304 | } |
300 | return 0; | 305 | return 0; |
301 | } | 306 | } |
302 | 307 | EXPORT_SYMBOL_GPL(w1_reset_select_slave); | |
303 | EXPORT_SYMBOL(w1_touch_bit); | ||
304 | EXPORT_SYMBOL(w1_write_8); | ||
305 | EXPORT_SYMBOL(w1_read_8); | ||
306 | EXPORT_SYMBOL(w1_reset_bus); | ||
307 | EXPORT_SYMBOL(w1_calc_crc8); | ||
308 | EXPORT_SYMBOL(w1_delay); | ||
309 | EXPORT_SYMBOL(w1_read_block); | ||
310 | EXPORT_SYMBOL(w1_write_block); | ||
311 | EXPORT_SYMBOL(w1_search_devices); | ||
312 | EXPORT_SYMBOL(w1_reset_select_slave); | ||
diff --git a/drivers/w1/w1_io.h b/drivers/w1/w1_io.h index 232860184a29..9a76d2ad69c5 100644 --- a/drivers/w1/w1_io.h +++ b/drivers/w1/w1_io.h | |||
@@ -24,11 +24,8 @@ | |||
24 | 24 | ||
25 | #include "w1.h" | 25 | #include "w1.h" |
26 | 26 | ||
27 | void w1_delay(unsigned long); | ||
28 | u8 w1_touch_bit(struct w1_master *, int); | ||
29 | u8 w1_triplet(struct w1_master *dev, int bdir); | 27 | u8 w1_triplet(struct w1_master *dev, int bdir); |
30 | void w1_write_8(struct w1_master *, u8); | 28 | void w1_write_8(struct w1_master *, u8); |
31 | u8 w1_read_8(struct w1_master *); | ||
32 | int w1_reset_bus(struct w1_master *); | 29 | int w1_reset_bus(struct w1_master *); |
33 | u8 w1_calc_crc8(u8 *, int); | 30 | u8 w1_calc_crc8(u8 *, int); |
34 | void w1_write_block(struct w1_master *, const u8 *, int); | 31 | void w1_write_block(struct w1_master *, const u8 *, int); |
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c index 328645da7972..65c5ebd0787e 100644 --- a/drivers/w1/w1_netlink.c +++ b/drivers/w1/w1_netlink.c | |||
@@ -21,72 +21,225 @@ | |||
21 | 21 | ||
22 | #include <linux/skbuff.h> | 22 | #include <linux/skbuff.h> |
23 | #include <linux/netlink.h> | 23 | #include <linux/netlink.h> |
24 | #include <linux/connector.h> | ||
24 | 25 | ||
25 | #include "w1.h" | 26 | #include "w1.h" |
26 | #include "w1_log.h" | 27 | #include "w1_log.h" |
27 | #include "w1_netlink.h" | 28 | #include "w1_netlink.h" |
28 | 29 | ||
29 | #ifndef NETLINK_DISABLED | 30 | #if defined(CONFIG_W1_CON) && (defined(CONFIG_CONNECTOR) || (defined(CONFIG_CONNECTOR_MODULE) && defined(CONFIG_W1_MODULE))) |
30 | void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) | 31 | void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) |
31 | { | 32 | { |
32 | unsigned int size; | 33 | char buf[sizeof(struct cn_msg) + sizeof(struct w1_netlink_msg)]; |
33 | struct sk_buff *skb; | 34 | struct cn_msg *m = (struct cn_msg *)buf; |
34 | struct w1_netlink_msg *data; | 35 | struct w1_netlink_msg *w = (struct w1_netlink_msg *)(m+1); |
35 | struct nlmsghdr *nlh; | ||
36 | 36 | ||
37 | if (!dev->nls) | 37 | memset(buf, 0, sizeof(buf)); |
38 | return; | ||
39 | 38 | ||
40 | size = NLMSG_SPACE(sizeof(struct w1_netlink_msg)); | 39 | m->id.idx = CN_W1_IDX; |
40 | m->id.val = CN_W1_VAL; | ||
41 | 41 | ||
42 | skb = alloc_skb(size, GFP_ATOMIC); | 42 | m->seq = dev->seq++; |
43 | if (!skb) { | 43 | m->len = sizeof(struct w1_netlink_msg); |
44 | dev_err(&dev->dev, "skb_alloc() failed.\n"); | 44 | |
45 | return; | 45 | memcpy(w, msg, sizeof(struct w1_netlink_msg)); |
46 | } | 46 | |
47 | cn_netlink_send(m, 0, GFP_KERNEL); | ||
48 | } | ||
49 | |||
50 | static int w1_process_command_master(struct w1_master *dev, struct cn_msg *msg, | ||
51 | struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) | ||
52 | { | ||
53 | dev_dbg(&dev->dev, "%s: %s: cmd=%02x, len=%u.\n", | ||
54 | __func__, dev->name, cmd->cmd, cmd->len); | ||
55 | |||
56 | if (cmd->cmd != W1_CMD_SEARCH && cmd->cmd != W1_CMD_ALARM_SEARCH) | ||
57 | return -EINVAL; | ||
58 | |||
59 | w1_search_process(dev, (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static int w1_send_read_reply(struct w1_slave *sl, struct cn_msg *msg, | ||
64 | struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) | ||
65 | { | ||
66 | void *data; | ||
67 | struct w1_netlink_msg *h; | ||
68 | struct w1_netlink_cmd *c; | ||
69 | struct cn_msg *cm; | ||
70 | int err; | ||
71 | |||
72 | data = kzalloc(sizeof(struct cn_msg) + | ||
73 | sizeof(struct w1_netlink_msg) + | ||
74 | sizeof(struct w1_netlink_cmd) + | ||
75 | cmd->len, GFP_KERNEL); | ||
76 | if (!data) | ||
77 | return -ENOMEM; | ||
78 | |||
79 | cm = (struct cn_msg *)(data); | ||
80 | h = (struct w1_netlink_msg *)(cm + 1); | ||
81 | c = (struct w1_netlink_cmd *)(h + 1); | ||
82 | |||
83 | memcpy(cm, msg, sizeof(struct cn_msg)); | ||
84 | memcpy(h, hdr, sizeof(struct w1_netlink_msg)); | ||
85 | memcpy(c, cmd, sizeof(struct w1_netlink_cmd)); | ||
47 | 86 | ||
48 | nlh = NLMSG_PUT(skb, 0, dev->seq++, NLMSG_DONE, size - sizeof(*nlh)); | 87 | cm->ack = msg->seq+1; |
88 | cm->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd) + cmd->len; | ||
49 | 89 | ||
50 | data = (struct w1_netlink_msg *)NLMSG_DATA(nlh); | 90 | h->len = sizeof(struct w1_netlink_cmd) + cmd->len; |
51 | 91 | ||
52 | memcpy(data, msg, sizeof(struct w1_netlink_msg)); | 92 | memcpy(c->data, cmd->data, c->len); |
53 | 93 | ||
54 | NETLINK_CB(skb).dst_group = dev->groups; | 94 | err = cn_netlink_send(cm, 0, GFP_KERNEL); |
55 | netlink_broadcast(dev->nls, skb, 0, dev->groups, GFP_ATOMIC); | ||
56 | 95 | ||
57 | nlmsg_failure: | 96 | kfree(data); |
58 | return; | 97 | |
98 | return err; | ||
59 | } | 99 | } |
60 | 100 | ||
61 | int dev_init_netlink(struct w1_master *dev) | 101 | static int w1_process_command_slave(struct w1_slave *sl, struct cn_msg *msg, |
102 | struct w1_netlink_msg *hdr, struct w1_netlink_cmd *cmd) | ||
62 | { | 103 | { |
63 | dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE); | 104 | int err = 0; |
64 | if (!dev->nls) { | 105 | |
65 | printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n", | 106 | dev_dbg(&sl->master->dev, "%s: %02x.%012llx.%02x: cmd=%02x, len=%u.\n", |
66 | NETLINK_W1, dev->dev.bus_id); | 107 | __func__, sl->reg_num.family, (unsigned long long)sl->reg_num.id, sl->reg_num.crc, |
108 | cmd->cmd, cmd->len); | ||
109 | |||
110 | switch (cmd->cmd) { | ||
111 | case W1_CMD_READ: | ||
112 | w1_read_block(sl->master, cmd->data, cmd->len); | ||
113 | w1_send_read_reply(sl, msg, hdr, cmd); | ||
114 | break; | ||
115 | case W1_CMD_WRITE: | ||
116 | w1_write_block(sl->master, cmd->data, cmd->len); | ||
117 | break; | ||
118 | case W1_CMD_SEARCH: | ||
119 | case W1_CMD_ALARM_SEARCH: | ||
120 | w1_search_process(sl->master, | ||
121 | (cmd->cmd == W1_CMD_ALARM_SEARCH)?W1_ALARM_SEARCH:W1_SEARCH); | ||
122 | break; | ||
123 | default: | ||
124 | err = -1; | ||
125 | break; | ||
67 | } | 126 | } |
68 | 127 | ||
69 | return 0; | 128 | return err; |
70 | } | 129 | } |
71 | 130 | ||
72 | void dev_fini_netlink(struct w1_master *dev) | 131 | static void w1_cn_callback(void *data) |
73 | { | 132 | { |
74 | if (dev->nls && dev->nls->sk_socket) | 133 | struct cn_msg *msg = data; |
75 | sock_release(dev->nls->sk_socket); | 134 | struct w1_netlink_msg *m = (struct w1_netlink_msg *)(msg + 1); |
135 | struct w1_netlink_cmd *cmd; | ||
136 | struct w1_slave *sl; | ||
137 | struct w1_master *dev; | ||
138 | int err = 0; | ||
139 | |||
140 | while (msg->len && !err) { | ||
141 | struct w1_reg_num id; | ||
142 | u16 mlen = m->len; | ||
143 | u8 *cmd_data = m->data; | ||
144 | |||
145 | dev = NULL; | ||
146 | sl = NULL; | ||
147 | |||
148 | memcpy(&id, m->id.id, sizeof(id)); | ||
149 | #if 0 | ||
150 | printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n", | ||
151 | __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len); | ||
152 | #endif | ||
153 | if (m->len + sizeof(struct w1_netlink_msg) > msg->len) { | ||
154 | err = -E2BIG; | ||
155 | break; | ||
156 | } | ||
157 | |||
158 | if (!mlen) | ||
159 | goto out_cont; | ||
160 | |||
161 | if (m->type == W1_MASTER_CMD) { | ||
162 | dev = w1_search_master_id(m->id.mst.id); | ||
163 | } else if (m->type == W1_SLAVE_CMD) { | ||
164 | sl = w1_search_slave(&id); | ||
165 | if (sl) | ||
166 | dev = sl->master; | ||
167 | } | ||
168 | |||
169 | if (!dev) { | ||
170 | err = -ENODEV; | ||
171 | goto out_cont; | ||
172 | } | ||
173 | |||
174 | mutex_lock(&dev->mutex); | ||
175 | |||
176 | if (sl && w1_reset_select_slave(sl)) { | ||
177 | err = -ENODEV; | ||
178 | goto out_up; | ||
179 | } | ||
180 | |||
181 | while (mlen) { | ||
182 | cmd = (struct w1_netlink_cmd *)cmd_data; | ||
183 | |||
184 | if (cmd->len + sizeof(struct w1_netlink_cmd) > mlen) { | ||
185 | err = -E2BIG; | ||
186 | break; | ||
187 | } | ||
188 | |||
189 | if (sl) | ||
190 | w1_process_command_slave(sl, msg, m, cmd); | ||
191 | else | ||
192 | w1_process_command_master(dev, msg, m, cmd); | ||
193 | |||
194 | cmd_data += cmd->len + sizeof(struct w1_netlink_cmd); | ||
195 | mlen -= cmd->len + sizeof(struct w1_netlink_cmd); | ||
196 | } | ||
197 | out_up: | ||
198 | atomic_dec(&dev->refcnt); | ||
199 | if (sl) | ||
200 | atomic_dec(&sl->refcnt); | ||
201 | mutex_unlock(&dev->mutex); | ||
202 | out_cont: | ||
203 | msg->len -= sizeof(struct w1_netlink_msg) + m->len; | ||
204 | m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len); | ||
205 | |||
206 | /* | ||
207 | * Let's allow requests for nonexisting devices. | ||
208 | */ | ||
209 | if (err == -ENODEV) | ||
210 | err = 0; | ||
211 | } | ||
212 | #if 0 | ||
213 | if (err) { | ||
214 | printk("%s: malformed message. Dropping.\n", __func__); | ||
215 | } | ||
216 | #endif | ||
76 | } | 217 | } |
77 | #else | ||
78 | #warning Netlink support is disabled. Please compile with NET support enabled. | ||
79 | 218 | ||
219 | int w1_init_netlink(void) | ||
220 | { | ||
221 | struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL}; | ||
222 | |||
223 | return cn_add_callback(&w1_id, "w1", &w1_cn_callback); | ||
224 | } | ||
225 | |||
226 | void w1_fini_netlink(void) | ||
227 | { | ||
228 | struct cb_id w1_id = {.idx = CN_W1_IDX, .val = CN_W1_VAL}; | ||
229 | |||
230 | cn_del_callback(&w1_id); | ||
231 | } | ||
232 | #else | ||
80 | void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) | 233 | void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg) |
81 | { | 234 | { |
82 | } | 235 | } |
83 | 236 | ||
84 | int dev_init_netlink(struct w1_master *dev) | 237 | int w1_init_netlink(void) |
85 | { | 238 | { |
86 | return 0; | 239 | return 0; |
87 | } | 240 | } |
88 | 241 | ||
89 | void dev_fini_netlink(struct w1_master *dev) | 242 | void w1_fini_netlink(void) |
90 | { | 243 | { |
91 | } | 244 | } |
92 | #endif | 245 | #endif |
diff --git a/drivers/w1/w1_netlink.h b/drivers/w1/w1_netlink.h index eb0c8b3152c8..56122b9e9294 100644 --- a/drivers/w1/w1_netlink.h +++ b/drivers/w1/w1_netlink.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #define __W1_NETLINK_H | 23 | #define __W1_NETLINK_H |
24 | 24 | ||
25 | #include <asm/types.h> | 25 | #include <asm/types.h> |
26 | #include <linux/connector.h> | ||
26 | 27 | ||
27 | #include "w1.h" | 28 | #include "w1.h" |
28 | 29 | ||
@@ -31,29 +32,43 @@ enum w1_netlink_message_types { | |||
31 | W1_SLAVE_REMOVE, | 32 | W1_SLAVE_REMOVE, |
32 | W1_MASTER_ADD, | 33 | W1_MASTER_ADD, |
33 | W1_MASTER_REMOVE, | 34 | W1_MASTER_REMOVE, |
35 | W1_MASTER_CMD, | ||
36 | W1_SLAVE_CMD, | ||
34 | }; | 37 | }; |
35 | 38 | ||
36 | struct w1_netlink_msg | 39 | struct w1_netlink_msg |
37 | { | 40 | { |
38 | __u8 type; | 41 | __u8 type; |
39 | __u8 reserved[3]; | 42 | __u8 reserved; |
40 | union | 43 | __u16 len; |
41 | { | 44 | union { |
42 | struct w1_reg_num id; | 45 | __u8 id[8]; |
43 | __u64 w1_id; | 46 | struct w1_mst { |
44 | struct | ||
45 | { | ||
46 | __u32 id; | 47 | __u32 id; |
47 | __u32 pid; | 48 | __u32 res; |
48 | } mst; | 49 | } mst; |
49 | } id; | 50 | } id; |
51 | __u8 data[0]; | ||
52 | }; | ||
53 | |||
54 | #define W1_CMD_READ 0x0 | ||
55 | #define W1_CMD_WRITE 0x1 | ||
56 | #define W1_CMD_SEARCH 0x2 | ||
57 | #define W1_CMD_ALARM_SEARCH 0x3 | ||
58 | |||
59 | struct w1_netlink_cmd | ||
60 | { | ||
61 | __u8 cmd; | ||
62 | __u8 res; | ||
63 | __u16 len; | ||
64 | __u8 data[0]; | ||
50 | }; | 65 | }; |
51 | 66 | ||
52 | #ifdef __KERNEL__ | 67 | #ifdef __KERNEL__ |
53 | 68 | ||
54 | void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *); | 69 | void w1_netlink_send(struct w1_master *, struct w1_netlink_msg *); |
55 | int dev_init_netlink(struct w1_master *dev); | 70 | int w1_init_netlink(void); |
56 | void dev_fini_netlink(struct w1_master *dev); | 71 | void w1_fini_netlink(void); |
57 | 72 | ||
58 | #endif /* __KERNEL__ */ | 73 | #endif /* __KERNEL__ */ |
59 | #endif /* __W1_NETLINK_H */ | 74 | #endif /* __W1_NETLINK_H */ |