Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
zfcp_cfdc.c
Go to the documentation of this file.
1 /*
2  * zfcp device driver
3  *
4  * Userspace interface for accessing the
5  * Access Control Lists / Control File Data Channel;
6  * handling of response code and states for ports and LUNs.
7  *
8  * Copyright IBM Corp. 2008, 2010
9  */
10 
11 #define KMSG_COMPONENT "zfcp"
12 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13 
14 #include <linux/compat.h>
15 #include <linux/slab.h>
16 #include <linux/types.h>
17 #include <linux/miscdevice.h>
18 #include <asm/compat.h>
19 #include <asm/ccwdev.h>
20 #include "zfcp_def.h"
21 #include "zfcp_ext.h"
22 #include "zfcp_fsf.h"
23 
24 #define ZFCP_CFDC_CMND_DOWNLOAD_NORMAL 0x00010001
25 #define ZFCP_CFDC_CMND_DOWNLOAD_FORCE 0x00010101
26 #define ZFCP_CFDC_CMND_FULL_ACCESS 0x00000201
27 #define ZFCP_CFDC_CMND_RESTRICTED_ACCESS 0x00000401
28 #define ZFCP_CFDC_CMND_UPLOAD 0x00010002
29 
30 #define ZFCP_CFDC_DOWNLOAD 0x00000001
31 #define ZFCP_CFDC_UPLOAD 0x00000002
32 #define ZFCP_CFDC_WITH_CONTROL_FILE 0x00010000
33 
34 #define ZFCP_CFDC_IOC_MAGIC 0xDD
35 #define ZFCP_CFDC_IOC \
36  _IOWR(ZFCP_CFDC_IOC_MAGIC, 0, struct zfcp_cfdc_data)
37 
54  u8 payloads[256];
56 };
57 
58 static int zfcp_cfdc_copy_from_user(struct scatterlist *sg,
59  void __user *user_buffer)
60 {
61  unsigned int length;
62  unsigned int size = ZFCP_CFDC_MAX_SIZE;
63 
64  while (size) {
65  length = min((unsigned int)size, sg->length);
66  if (copy_from_user(sg_virt(sg++), user_buffer, length))
67  return -EFAULT;
68  user_buffer += length;
69  size -= length;
70  }
71  return 0;
72 }
73 
74 static int zfcp_cfdc_copy_to_user(void __user *user_buffer,
75  struct scatterlist *sg)
76 {
77  unsigned int length;
78  unsigned int size = ZFCP_CFDC_MAX_SIZE;
79 
80  while (size) {
81  length = min((unsigned int) size, sg->length);
82  if (copy_to_user(user_buffer, sg_virt(sg++), length))
83  return -EFAULT;
84  user_buffer += length;
85  size -= length;
86  }
87  return 0;
88 }
89 
90 static struct zfcp_adapter *zfcp_cfdc_get_adapter(u32 devno)
91 {
92  char busid[9];
93  struct ccw_device *cdev;
94  struct zfcp_adapter *adapter;
95 
96  snprintf(busid, sizeof(busid), "0.0.%04x", devno);
97  cdev = get_ccwdev_by_busid(&zfcp_ccw_driver, busid);
98  if (!cdev)
99  return NULL;
100 
101  adapter = zfcp_ccw_adapter_by_cdev(cdev);
102 
103  put_device(&cdev->dev);
104  return adapter;
105 }
106 
107 static int zfcp_cfdc_set_fsf(struct zfcp_fsf_cfdc *fsf_cfdc, int command)
108 {
109  switch (command) {
113  break;
116  fsf_cfdc->option = FSF_CFDC_OPTION_FORCE;
117  break;
121  break;
125  break;
128  fsf_cfdc->option = 0;
129  break;
130  default:
131  return -EINVAL;
132  }
133 
134  return 0;
135 }
136 
137 static int zfcp_cfdc_sg_setup(int command, struct scatterlist *sg,
138  u8 __user *control_file)
139 {
140  int retval;
141  retval = zfcp_sg_setup_table(sg, ZFCP_CFDC_PAGES);
142  if (retval)
143  return retval;
144 
146 
147  if (command & ZFCP_CFDC_WITH_CONTROL_FILE &&
148  command & ZFCP_CFDC_DOWNLOAD) {
149  retval = zfcp_cfdc_copy_from_user(sg, control_file);
150  if (retval) {
152  return -EFAULT;
153  }
154  }
155 
156  return 0;
157 }
158 
159 static void zfcp_cfdc_req_to_sense(struct zfcp_cfdc_data *data,
160  struct zfcp_fsf_req *req)
161 {
162  data->fsf_status = req->qtcb->header.fsf_status;
163  memcpy(&data->fsf_status_qual, &req->qtcb->header.fsf_status_qual,
164  sizeof(union fsf_status_qual));
165  memcpy(&data->payloads, &req->qtcb->bottom.support.els,
166  sizeof(req->qtcb->bottom.support.els));
167 }
168 
169 static long zfcp_cfdc_dev_ioctl(struct file *file, unsigned int command,
170  unsigned long arg)
171 {
172  struct zfcp_cfdc_data *data;
173  struct zfcp_cfdc_data __user *data_user;
174  struct zfcp_adapter *adapter;
175  struct zfcp_fsf_req *req;
176  struct zfcp_fsf_cfdc *fsf_cfdc;
177  int retval;
178 
179  if (command != ZFCP_CFDC_IOC)
180  return -ENOTTY;
181 
182  if (is_compat_task())
183  data_user = compat_ptr(arg);
184  else
185  data_user = (void __user *)arg;
186 
187  if (!data_user)
188  return -EINVAL;
189 
190  fsf_cfdc = kmalloc(sizeof(struct zfcp_fsf_cfdc), GFP_KERNEL);
191  if (!fsf_cfdc)
192  return -ENOMEM;
193 
194  data = memdup_user(data_user, sizeof(*data_user));
195  if (IS_ERR(data)) {
196  retval = PTR_ERR(data);
197  goto no_mem_sense;
198  }
199 
200  if (data->signature != 0xCFDCACDF) {
201  retval = -EINVAL;
202  goto free_buffer;
203  }
204 
205  retval = zfcp_cfdc_set_fsf(fsf_cfdc, data->command);
206 
207  adapter = zfcp_cfdc_get_adapter(data->devno);
208  if (!adapter) {
209  retval = -ENXIO;
210  goto free_buffer;
211  }
212 
213  retval = zfcp_cfdc_sg_setup(data->command, fsf_cfdc->sg,
214  data_user->control_file);
215  if (retval)
216  goto adapter_put;
217  req = zfcp_fsf_control_file(adapter, fsf_cfdc);
218  if (IS_ERR(req)) {
219  retval = PTR_ERR(req);
220  goto free_sg;
221  }
222 
223  if (req->status & ZFCP_STATUS_FSFREQ_ERROR) {
224  retval = -ENXIO;
225  goto free_fsf;
226  }
227 
228  zfcp_cfdc_req_to_sense(data, req);
229  retval = copy_to_user(data_user, data, sizeof(*data_user));
230  if (retval) {
231  retval = -EFAULT;
232  goto free_fsf;
233  }
234 
235  if (data->command & ZFCP_CFDC_UPLOAD)
236  retval = zfcp_cfdc_copy_to_user(&data_user->control_file,
237  fsf_cfdc->sg);
238 
239  free_fsf:
240  zfcp_fsf_req_free(req);
241  free_sg:
243  adapter_put:
244  zfcp_ccw_adapter_put(adapter);
245  free_buffer:
246  kfree(data);
247  no_mem_sense:
248  kfree(fsf_cfdc);
249  return retval;
250 }
251 
252 static const struct file_operations zfcp_cfdc_fops = {
253  .open = nonseekable_open,
254  .unlocked_ioctl = zfcp_cfdc_dev_ioctl,
255 #ifdef CONFIG_COMPAT
256  .compat_ioctl = zfcp_cfdc_dev_ioctl,
257 #endif
258  .llseek = no_llseek,
259 };
260 
262  .minor = MISC_DYNAMIC_MINOR,
263  .name = "zfcp_cfdc",
264  .fops = &zfcp_cfdc_fops,
265 };
266 
275 {
276  unsigned long flags;
277  struct zfcp_port *port;
278  struct scsi_device *sdev;
279  struct zfcp_scsi_dev *zfcp_sdev;
280  int status;
281 
283  return;
284 
285  read_lock_irqsave(&adapter->port_list_lock, flags);
286  list_for_each_entry(port, &adapter->port_list, list) {
287  status = atomic_read(&port->status);
288  if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
292  "cfaac_1");
293  }
294  read_unlock_irqrestore(&adapter->port_list_lock, flags);
295 
296  shost_for_each_device(sdev, adapter->scsi_host) {
297  zfcp_sdev = sdev_to_zfcp(sdev);
298  status = atomic_read(&zfcp_sdev->status);
299  if ((status & ZFCP_STATUS_COMMON_ACCESS_DENIED) ||
301  zfcp_erp_lun_reopen(sdev,
303  "cfaac_2");
304  }
305 }
306 
307 static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table)
308 {
309  u16 subtable = table >> 16;
310  u16 rule = table & 0xffff;
311  const char *act_type[] = { "unknown", "OS", "WWPN", "DID", "LUN" };
312 
313  if (subtable && subtable < ARRAY_SIZE(act_type))
314  dev_warn(&adapter->ccw_device->dev,
315  "Access denied according to ACT rule type %s, "
316  "rule %d\n", act_type[subtable], rule);
317 }
318 
325  union fsf_status_qual *qual)
326 {
327  dev_warn(&port->adapter->ccw_device->dev,
328  "Access denied to port 0x%016Lx\n",
329  (unsigned long long)port->wwpn);
330 
331  zfcp_act_eval_err(port->adapter, qual->halfword[0]);
332  zfcp_act_eval_err(port->adapter, qual->halfword[1]);
336 }
337 
344  union fsf_status_qual *qual)
345 {
346  struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
347 
348  dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
349  "Access denied to LUN 0x%016Lx on port 0x%016Lx\n",
350  zfcp_scsi_dev_lun(sdev),
351  (unsigned long long)zfcp_sdev->port->wwpn);
352  zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[0]);
353  zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->halfword[1]);
357 
360 }
361 
368  union fsf_status_qual *qual)
369 {
370  struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
371 
372  if (qual->word[0])
373  dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
374  "LUN 0x%Lx on port 0x%Lx is already in "
375  "use by CSS%d, MIF Image ID %x\n",
376  zfcp_scsi_dev_lun(sdev),
377  (unsigned long long)zfcp_sdev->port->wwpn,
378  qual->fsf_queue_designator.cssid,
379  qual->fsf_queue_designator.hla);
380  else
381  zfcp_act_eval_err(zfcp_sdev->port->adapter, qual->word[2]);
382 
388 }
389 
400 {
401  int shared, rw;
402  struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
403  struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
404 
405  if ((adapter->connection_features & FSF_FEATURE_NPIV_MODE) ||
407  zfcp_ccw_priv_sch(adapter))
408  return 0;
409 
410  shared = !(bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE);
412 
413  if (shared)
415 
416  if (!rw) {
418  dev_info(&adapter->ccw_device->dev, "SCSI device at LUN "
419  "0x%016Lx on port 0x%016Lx opened read-only\n",
420  zfcp_scsi_dev_lun(sdev),
421  (unsigned long long)zfcp_sdev->port->wwpn);
422  }
423 
424  if (!shared && !rw) {
425  dev_err(&adapter->ccw_device->dev, "Exclusive read-only access "
426  "not supported (LUN 0x%016Lx, port 0x%016Lx)\n",
427  zfcp_scsi_dev_lun(sdev),
428  (unsigned long long)zfcp_sdev->port->wwpn);
430  zfcp_erp_lun_shutdown(sdev, 0, "fsouh_6");
431  return -EACCES;
432  }
433 
434  if (shared && rw) {
435  dev_err(&adapter->ccw_device->dev,
436  "Shared read-write access not supported "
437  "(LUN 0x%016Lx, port 0x%016Lx)\n",
438  zfcp_scsi_dev_lun(sdev),
439  (unsigned long long)zfcp_sdev->port->wwpn);
441  zfcp_erp_lun_shutdown(sdev, 0, "fsosh_8");
442  return -EACCES;
443  }
444 
445  return 0;
446 }