aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/arcmsr/arcmsr_attr.c
diff options
context:
space:
mode:
authorNick Cheng <nick.cheng@areca.com.tw>2007-09-13 05:26:40 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:48:27 -0400
commit1a4f550a09f89e3a15eff1971bc9db977571b9f6 (patch)
tree3ba5dea468391701664d4ca4c0b0e2a569521d89 /drivers/scsi/arcmsr/arcmsr_attr.c
parentbfd129445f23c037d9a440ebfa4109e11c220301 (diff)
[SCSI] arcmsr: 1.20.00.15: add SATA RAID plus other fixes
Description: ** support ARC1200/1201/1202 SATA RAID adapter, which is named ACB_ADAPTER_TYPE_B ** modify the arcmsr_pci_slot_reset function ** modify the arcmsr_pci_ers_disconnect_forepart function ** modify the arcmsr_pci_ers_need_reset_forepart function  Signed-off-by: Nick Cheng <nick.cheng@areca.com.tw> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/arcmsr/arcmsr_attr.c')
-rw-r--r--drivers/scsi/arcmsr/arcmsr_attr.c64
1 files changed, 24 insertions, 40 deletions
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c
index 06c0dce3b83..0f0a1ae9943 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
59struct class_device_attribute *arcmsr_host_attrs[]; 60struct class_device_attribute *arcmsr_host_attrs[];
60 61
61static ssize_t 62static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
62arcmsr_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 &reg->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 &reg->inbound_doorbell);
104 } 101 }
105 return (allxfer_len); 102 return (allxfer_len);
106} 103}
107 104
108static ssize_t 105static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, char *buf, loff_t off, size_t count)
109arcmsr_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
156static ssize_t 150static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, char *buf, loff_t off, size_t count)
157arcmsr_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 , &reg->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;
241error_bin_file_message_clear: 230error_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);
244error_bin_file_message_write: 232error_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);
247error_bin_file_message_read: 234error_bin_file_message_read:
248 return error; 235 return error;
249} 236}
@@ -252,12 +239,9 @@ void
252arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { 239arcmsr_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