diff options
Diffstat (limited to 'drivers/scsi/arcmsr/arcmsr_attr.c')
-rw-r--r-- | drivers/scsi/arcmsr/arcmsr_attr.c | 64 |
1 files changed, 24 insertions, 40 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 06c0dce3b839..0f0a1ae99434 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c | |||
@@ -8,7 +8,7 @@ | |||
8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved | 8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved |
9 | ** | 9 | ** |
10 | ** Web site: www.areca.com.tw | 10 | ** Web site: www.areca.com.tw |
11 | ** E-mail: erich@areca.com.tw | 11 | ** E-mail: support@areca.com.tw |
12 | ** | 12 | ** |
13 | ** This program is free software; you can redistribute it and/or modify | 13 | ** This program is free software; you can redistribute it and/or modify |
14 | ** it under the terms of the GNU General Public License version 2 as | 14 | ** it under the terms of the GNU General Public License version 2 as |
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
51 | #include <linux/delay.h> | 51 | #include <linux/delay.h> |
52 | #include <linux/pci.h> | ||
52 | 53 | ||
53 | #include <scsi/scsi_cmnd.h> | 54 | #include <scsi/scsi_cmnd.h> |
54 | #include <scsi/scsi_device.h> | 55 | #include <scsi/scsi_device.h> |
@@ -58,15 +59,11 @@ | |||
58 | 59 | ||
59 | struct class_device_attribute *arcmsr_host_attrs[]; | 60 | struct class_device_attribute *arcmsr_host_attrs[]; |
60 | 61 | ||
61 | static ssize_t | 62 | static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, size_t count) |
62 | arcmsr_sysfs_iop_message_read(struct kobject *kobj, | ||
63 | struct bin_attribute *bin_attr, | ||
64 | char *buf, loff_t off, size_t count) | ||
65 | { | 63 | { |
66 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 64 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
67 | struct Scsi_Host *host = class_to_shost(cdev); | 65 | struct Scsi_Host *host = class_to_shost(cdev); |
68 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 66 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
69 | struct MessageUnit __iomem *reg = acb->pmu; | ||
70 | uint8_t *pQbuffer,*ptmpQbuffer; | 67 | uint8_t *pQbuffer,*ptmpQbuffer; |
71 | int32_t allxfer_len = 0; | 68 | int32_t allxfer_len = 0; |
72 | 69 | ||
@@ -85,12 +82,13 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, | |||
85 | allxfer_len++; | 82 | allxfer_len++; |
86 | } | 83 | } |
87 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 84 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
88 | struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) | 85 | struct QBUFFER *prbuffer; |
89 | ®->message_rbuffer; | 86 | uint8_t *iop_data; |
90 | uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; | ||
91 | int32_t iop_len; | 87 | int32_t iop_len; |
92 | 88 | ||
93 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 89 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
90 | prbuffer = arcmsr_get_iop_rqbuffer(acb); | ||
91 | iop_data = (uint8_t *)prbuffer->data; | ||
94 | iop_len = readl(&prbuffer->data_len); | 92 | iop_len = readl(&prbuffer->data_len); |
95 | while (iop_len > 0) { | 93 | while (iop_len > 0) { |
96 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); | 94 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); |
@@ -99,16 +97,12 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, | |||
99 | iop_data++; | 97 | iop_data++; |
100 | iop_len--; | 98 | iop_len--; |
101 | } | 99 | } |
102 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, | 100 | arcmsr_iop_message_read(acb); |
103 | ®->inbound_doorbell); | ||
104 | } | 101 | } |
105 | return (allxfer_len); | 102 | return (allxfer_len); |
106 | } | 103 | } |
107 | 104 | ||
108 | static ssize_t | 105 | static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, size_t count) |
109 | arcmsr_sysfs_iop_message_write(struct kobject *kobj, | ||
110 | struct bin_attribute *bin_attr, | ||
111 | char *buf, loff_t off, size_t count) | ||
112 | { | 106 | { |
113 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 107 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
114 | struct Scsi_Host *host = class_to_shost(cdev); | 108 | struct Scsi_Host *host = class_to_shost(cdev); |
@@ -126,7 +120,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
126 | wqbuf_lastindex = acb->wqbuf_lastindex; | 120 | wqbuf_lastindex = acb->wqbuf_lastindex; |
127 | wqbuf_firstindex = acb->wqbuf_firstindex; | 121 | wqbuf_firstindex = acb->wqbuf_firstindex; |
128 | if (wqbuf_lastindex != wqbuf_firstindex) { | 122 | if (wqbuf_lastindex != wqbuf_firstindex) { |
129 | arcmsr_post_Qbuffer(acb); | 123 | arcmsr_post_ioctldata2iop(acb); |
130 | return 0; /*need retry*/ | 124 | return 0; /*need retry*/ |
131 | } else { | 125 | } else { |
132 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) | 126 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) |
@@ -144,7 +138,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
144 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { | 138 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { |
145 | acb->acb_flags &= | 139 | acb->acb_flags &= |
146 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; | 140 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; |
147 | arcmsr_post_Qbuffer(acb); | 141 | arcmsr_post_ioctldata2iop(acb); |
148 | } | 142 | } |
149 | return count; | 143 | return count; |
150 | } else { | 144 | } else { |
@@ -153,15 +147,11 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
153 | } | 147 | } |
154 | } | 148 | } |
155 | 149 | ||
156 | static ssize_t | 150 | static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, size_t count) |
157 | arcmsr_sysfs_iop_message_clear(struct kobject *kobj, | ||
158 | struct bin_attribute *bin_attr, | ||
159 | char *buf, loff_t off, size_t count) | ||
160 | { | 151 | { |
161 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 152 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
162 | struct Scsi_Host *host = class_to_shost(cdev); | 153 | struct Scsi_Host *host = class_to_shost(cdev); |
163 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 154 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
164 | struct MessageUnit __iomem *reg = acb->pmu; | ||
165 | uint8_t *pQbuffer; | 155 | uint8_t *pQbuffer; |
166 | 156 | ||
167 | if (!capable(CAP_SYS_ADMIN)) | 157 | if (!capable(CAP_SYS_ADMIN)) |
@@ -169,8 +159,7 @@ arcmsr_sysfs_iop_message_clear(struct kobject *kobj, | |||
169 | 159 | ||
170 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 160 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
171 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 161 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
172 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK | 162 | arcmsr_iop_message_read(acb); |
173 | , ®->inbound_doorbell); | ||
174 | } | 163 | } |
175 | acb->acb_flags |= | 164 | acb->acb_flags |= |
176 | (ACB_F_MESSAGE_WQBUFFER_CLEARED | 165 | (ACB_F_MESSAGE_WQBUFFER_CLEARED |
@@ -191,6 +180,7 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { | |||
191 | .attr = { | 180 | .attr = { |
192 | .name = "mu_read", | 181 | .name = "mu_read", |
193 | .mode = S_IRUSR , | 182 | .mode = S_IRUSR , |
183 | .owner = THIS_MODULE, | ||
194 | }, | 184 | }, |
195 | .size = 1032, | 185 | .size = 1032, |
196 | .read = arcmsr_sysfs_iop_message_read, | 186 | .read = arcmsr_sysfs_iop_message_read, |
@@ -200,6 +190,7 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { | |||
200 | .attr = { | 190 | .attr = { |
201 | .name = "mu_write", | 191 | .name = "mu_write", |
202 | .mode = S_IWUSR, | 192 | .mode = S_IWUSR, |
193 | .owner = THIS_MODULE, | ||
203 | }, | 194 | }, |
204 | .size = 1032, | 195 | .size = 1032, |
205 | .write = arcmsr_sysfs_iop_message_write, | 196 | .write = arcmsr_sysfs_iop_message_write, |
@@ -209,6 +200,7 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { | |||
209 | .attr = { | 200 | .attr = { |
210 | .name = "mu_clear", | 201 | .name = "mu_clear", |
211 | .mode = S_IWUSR, | 202 | .mode = S_IWUSR, |
203 | .owner = THIS_MODULE, | ||
212 | }, | 204 | }, |
213 | .size = 1, | 205 | .size = 1, |
214 | .write = arcmsr_sysfs_iop_message_clear, | 206 | .write = arcmsr_sysfs_iop_message_clear, |
@@ -219,31 +211,26 @@ int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb) | |||
219 | struct Scsi_Host *host = acb->host; | 211 | struct Scsi_Host *host = acb->host; |
220 | int error; | 212 | int error; |
221 | 213 | ||
222 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 214 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
223 | &arcmsr_sysfs_message_read_attr); | ||
224 | if (error) { | 215 | if (error) { |
225 | printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); | 216 | printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); |
226 | goto error_bin_file_message_read; | 217 | goto error_bin_file_message_read; |
227 | } | 218 | } |
228 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 219 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
229 | &arcmsr_sysfs_message_write_attr); | ||
230 | if (error) { | 220 | if (error) { |
231 | printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); | 221 | printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); |
232 | goto error_bin_file_message_write; | 222 | goto error_bin_file_message_write; |
233 | } | 223 | } |
234 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 224 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); |
235 | &arcmsr_sysfs_message_clear_attr); | ||
236 | if (error) { | 225 | if (error) { |
237 | printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); | 226 | printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); |
238 | goto error_bin_file_message_clear; | 227 | goto error_bin_file_message_clear; |
239 | } | 228 | } |
240 | return 0; | 229 | return 0; |
241 | error_bin_file_message_clear: | 230 | error_bin_file_message_clear: |
242 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 231 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
243 | &arcmsr_sysfs_message_write_attr); | ||
244 | error_bin_file_message_write: | 232 | error_bin_file_message_write: |
245 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 233 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
246 | &arcmsr_sysfs_message_read_attr); | ||
247 | error_bin_file_message_read: | 234 | error_bin_file_message_read: |
248 | return error; | 235 | return error; |
249 | } | 236 | } |
@@ -252,12 +239,9 @@ void | |||
252 | arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { | 239 | arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { |
253 | struct Scsi_Host *host = acb->host; | 240 | struct Scsi_Host *host = acb->host; |
254 | 241 | ||
255 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 242 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); |
256 | &arcmsr_sysfs_message_clear_attr); | 243 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
257 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 244 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
258 | &arcmsr_sysfs_message_write_attr); | ||
259 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | ||
260 | &arcmsr_sysfs_message_read_attr); | ||
261 | } | 245 | } |
262 | 246 | ||
263 | 247 | ||