diff options
author | Daniel Drake <dsd@gentoo.org> | 2006-12-11 20:26:11 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-05 16:58:42 -0500 |
commit | 0ce34bc8f7d906d66ce6803f63399ef9bbe54012 (patch) | |
tree | 1326f9105842fc81f89bf8ab1a435ab13a4d72d5 /drivers/net/wireless/zd1211rw/zd_usb.c | |
parent | ee30276774451d657407855d95d9393ee8bc0bac (diff) |
[PATCH] zd1211rw: Remove addressing abstraction
Instead of passing our own custom 32-bit addresses around and
translating them, this patch makes all our register address constants
absolute and removes the translation.
There are two ugly parts:
- fw_reg_addr() is needed to compute addresses of firmware registers, as this
is dynamic based upon firmware
- inc_addr() needs a small hack to handle byte vs word addressing
However, both of those are only small, and we don't use fw_regs a whole
lot anyway.
The bonuses here include simplicity and improved driver readability. Also, the
fact that registers are now referenced by 16-bit absolute addresses (as
opposed to 32-bit pseudo addresses) means that over 2kb compiled code size has
been shaved off.
Includes some touchups and sparse fixes from Ulrich Kunitz.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_usb.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 112 |
1 files changed, 3 insertions, 109 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 6a524409aeac..9025ad9e9d34 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -75,96 +75,6 @@ MODULE_DEVICE_TABLE(usb, usb_ids); | |||
75 | #define FW_ZD1211_PREFIX "zd1211/zd1211_" | 75 | #define FW_ZD1211_PREFIX "zd1211/zd1211_" |
76 | #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" | 76 | #define FW_ZD1211B_PREFIX "zd1211/zd1211b_" |
77 | 77 | ||
78 | /* register address handling */ | ||
79 | |||
80 | #ifdef DEBUG | ||
81 | static int check_addr(struct zd_usb *usb, zd_addr_t addr) | ||
82 | { | ||
83 | u32 base = ZD_ADDR_BASE(addr); | ||
84 | u32 offset = ZD_OFFSET(addr); | ||
85 | |||
86 | if ((u32)addr & ADDR_ZERO_MASK) | ||
87 | goto invalid_address; | ||
88 | switch (base) { | ||
89 | case USB_BASE: | ||
90 | break; | ||
91 | case CR_BASE: | ||
92 | if (offset > CR_MAX_OFFSET) { | ||
93 | dev_dbg(zd_usb_dev(usb), | ||
94 | "CR offset %#010x larger than" | ||
95 | " CR_MAX_OFFSET %#10x\n", | ||
96 | offset, CR_MAX_OFFSET); | ||
97 | goto invalid_address; | ||
98 | } | ||
99 | if (offset & 1) { | ||
100 | dev_dbg(zd_usb_dev(usb), | ||
101 | "CR offset %#010x is not a multiple of 2\n", | ||
102 | offset); | ||
103 | goto invalid_address; | ||
104 | } | ||
105 | break; | ||
106 | case E2P_BASE: | ||
107 | if (offset > E2P_MAX_OFFSET) { | ||
108 | dev_dbg(zd_usb_dev(usb), | ||
109 | "E2P offset %#010x larger than" | ||
110 | " E2P_MAX_OFFSET %#010x\n", | ||
111 | offset, E2P_MAX_OFFSET); | ||
112 | goto invalid_address; | ||
113 | } | ||
114 | break; | ||
115 | case FW_BASE: | ||
116 | if (!usb->fw_base_offset) { | ||
117 | dev_dbg(zd_usb_dev(usb), | ||
118 | "ERROR: fw base offset has not been set\n"); | ||
119 | return -EAGAIN; | ||
120 | } | ||
121 | if (offset > FW_MAX_OFFSET) { | ||
122 | dev_dbg(zd_usb_dev(usb), | ||
123 | "FW offset %#10x is larger than" | ||
124 | " FW_MAX_OFFSET %#010x\n", | ||
125 | offset, FW_MAX_OFFSET); | ||
126 | goto invalid_address; | ||
127 | } | ||
128 | break; | ||
129 | default: | ||
130 | dev_dbg(zd_usb_dev(usb), | ||
131 | "address has unsupported base %#010x\n", addr); | ||
132 | goto invalid_address; | ||
133 | } | ||
134 | |||
135 | return 0; | ||
136 | invalid_address: | ||
137 | dev_dbg(zd_usb_dev(usb), | ||
138 | "ERROR: invalid address: %#010x\n", addr); | ||
139 | return -EINVAL; | ||
140 | } | ||
141 | #endif /* DEBUG */ | ||
142 | |||
143 | static u16 usb_addr(struct zd_usb *usb, zd_addr_t addr) | ||
144 | { | ||
145 | u32 base; | ||
146 | u16 offset; | ||
147 | |||
148 | base = ZD_ADDR_BASE(addr); | ||
149 | offset = ZD_OFFSET(addr); | ||
150 | |||
151 | ZD_ASSERT(check_addr(usb, addr) == 0); | ||
152 | |||
153 | switch (base) { | ||
154 | case CR_BASE: | ||
155 | offset += CR_START; | ||
156 | break; | ||
157 | case E2P_BASE: | ||
158 | offset += E2P_START + E2P_DATA_OFFSET; | ||
159 | break; | ||
160 | case FW_BASE: | ||
161 | offset += usb->fw_base_offset; | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | return offset; | ||
166 | } | ||
167 | |||
168 | /* USB device initialization */ | 78 | /* USB device initialization */ |
169 | 79 | ||
170 | static int request_fw_file( | 80 | static int request_fw_file( |
@@ -858,7 +768,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb) | |||
858 | spin_lock_init(&intr->lock); | 768 | spin_lock_init(&intr->lock); |
859 | intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); | 769 | intr->interval = int_urb_interval(zd_usb_to_usbdev(usb)); |
860 | init_completion(&intr->read_regs.completion); | 770 | init_completion(&intr->read_regs.completion); |
861 | intr->read_regs.cr_int_addr = cpu_to_le16(usb_addr(usb, CR_INTERRUPT)); | 771 | intr->read_regs.cr_int_addr = cpu_to_le16((u16)CR_INTERRUPT); |
862 | } | 772 | } |
863 | 773 | ||
864 | static inline void init_usb_rx(struct zd_usb *usb) | 774 | static inline void init_usb_rx(struct zd_usb *usb) |
@@ -890,22 +800,6 @@ void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, | |||
890 | init_usb_rx(usb); | 800 | init_usb_rx(usb); |
891 | } | 801 | } |
892 | 802 | ||
893 | int zd_usb_init_hw(struct zd_usb *usb) | ||
894 | { | ||
895 | int r; | ||
896 | struct zd_chip *chip = zd_usb_to_chip(usb); | ||
897 | |||
898 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | ||
899 | r = zd_ioread16_locked(chip, &usb->fw_base_offset, | ||
900 | USB_REG(FW_START + FW_REGS_ADDR_OFFSET)); | ||
901 | if (r) | ||
902 | return r; | ||
903 | dev_dbg_f(zd_usb_dev(usb), "fw_base_offset: %#06hx\n", | ||
904 | usb->fw_base_offset); | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | void zd_usb_clear(struct zd_usb *usb) | 803 | void zd_usb_clear(struct zd_usb *usb) |
910 | { | 804 | { |
911 | usb_set_intfdata(usb->intf, NULL); | 805 | usb_set_intfdata(usb->intf, NULL); |
@@ -1253,7 +1147,7 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1253 | return -ENOMEM; | 1147 | return -ENOMEM; |
1254 | req->id = cpu_to_le16(USB_REQ_READ_REGS); | 1148 | req->id = cpu_to_le16(USB_REQ_READ_REGS); |
1255 | for (i = 0; i < count; i++) | 1149 | for (i = 0; i < count; i++) |
1256 | req->addr[i] = cpu_to_le16(usb_addr(usb, addresses[i])); | 1150 | req->addr[i] = cpu_to_le16((u16)addresses[i]); |
1257 | 1151 | ||
1258 | udev = zd_usb_to_usbdev(usb); | 1152 | udev = zd_usb_to_usbdev(usb); |
1259 | prepare_read_regs_int(usb); | 1153 | prepare_read_regs_int(usb); |
@@ -1318,7 +1212,7 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1318 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); | 1212 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); |
1319 | for (i = 0; i < count; i++) { | 1213 | for (i = 0; i < count; i++) { |
1320 | struct reg_data *rw = &req->reg_writes[i]; | 1214 | struct reg_data *rw = &req->reg_writes[i]; |
1321 | rw->addr = cpu_to_le16(usb_addr(usb, ioreqs[i].addr)); | 1215 | rw->addr = cpu_to_le16((u16)ioreqs[i].addr); |
1322 | rw->value = cpu_to_le16(ioreqs[i].value); | 1216 | rw->value = cpu_to_le16(ioreqs[i].value); |
1323 | } | 1217 | } |
1324 | 1218 | ||