]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - drivers/staging/unisys/virthba/virthba.c
Merge tag 'pinctrl-v4.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[mirror_ubuntu-zesty-kernel.git] / drivers / staging / unisys / virthba / virthba.c
CommitLineData
dc950861
KC
1/* virthba.c
2 *
f6d0c1e6 3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
dc950861
KC
4 * All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at
9 * your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
14 * NON INFRINGEMENT. See the GNU General Public License for more
15 * details.
16 */
17
18#define EXPORT_SYMTAB
19
20/* if you want to turn on some debugging of write device data or read
21 * device data, define these two undefs. You will probably want to
22 * customize the code which is here since it was written assuming
23 * reading and writing a specific data file df.64M.txt which is a
24 * 64Megabyte file created by Art Nilson using a scritp I wrote called
25 * cr_test_data.pl. The data file consists of 256 byte lines of text
26 * which start with an 8 digit sequence number, a colon, and then
27 * letters after that */
28
dc950861
KC
29#include <linux/kernel.h>
30#ifdef CONFIG_MODVERSIONS
31#include <config/modversions.h>
32#endif
33
dc950861
KC
34#include "diagnostics/appos_subsystems.h"
35#include "uisutils.h"
36#include "uisqueue.h"
37#include "uisthread.h"
38
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/pci.h>
42#include <linux/spinlock.h>
43#include <linux/device.h>
44#include <linux/slab.h>
45#include <scsi/scsi.h>
46#include <scsi/scsi_host.h>
47#include <scsi/scsi_cmnd.h>
48#include <scsi/scsi_device.h>
49#include <asm/param.h>
d9c5607e 50#include <linux/debugfs.h>
dc950861
KC
51#include <linux/types.h>
52
53#include "virthba.h"
54#include "virtpci.h"
55#include "visorchipset.h"
56#include "version.h"
57#include "guestlinuxdebug.h"
58/* this is shorter than using __FILE__ (full path name) in
59 * debug/info/error messages
60 */
61#define CURRENT_FILE_PC VIRT_HBA_PC_virthba_c
62#define __MYFILE__ "virthba.c"
63
64/* NOTE: L1_CACHE_BYTES >=128 */
65#define DEVICE_ATTRIBUTE struct device_attribute
66
d9c5607e
EA
67 /* MAX_BUF = 6 lines x 10 MAXVHBA x 80 characters
68 * = 4800 bytes ~ 2^13 = 8192 bytes
69 */
70#define MAX_BUF 8192
71
dc950861
KC
72/*****************************************************/
73/* Forward declarations */
74/*****************************************************/
75static int virthba_probe(struct virtpci_dev *dev,
76 const struct pci_device_id *id);
77static void virthba_remove(struct virtpci_dev *dev);
78static int virthba_abort_handler(struct scsi_cmnd *scsicmd);
79static int virthba_bus_reset_handler(struct scsi_cmnd *scsicmd);
80static int virthba_device_reset_handler(struct scsi_cmnd *scsicmd);
81static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd);
82static const char *virthba_get_info(struct Scsi_Host *shp);
83static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
84static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
fb649950
KD
85 void (*virthba_cmnd_done)
86 (struct scsi_cmnd *));
a8d7f21d 87
87995171
KC
88static const struct x86_cpu_id unisys_spar_ids[] = {
89 { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
90 {}
91};
92
93/* Autoload */
94MODULE_DEVICE_TABLE(x86cpu, unisys_spar_ids);
95
dc950861 96#ifdef DEF_SCSI_QCMD
385914c3 97static DEF_SCSI_QCMD(virthba_queue_command)
dc950861
KC
98#else
99#define virthba_queue_command virthba_queue_command_lck
100#endif
a8d7f21d 101
dc950861
KC
102static int virthba_slave_alloc(struct scsi_device *scsidev);
103static int virthba_slave_configure(struct scsi_device *scsidev);
104static void virthba_slave_destroy(struct scsi_device *scsidev);
105static int process_incoming_rsps(void *);
106static int virthba_serverup(struct virtpci_dev *virtpcidev);
107static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
b6e0a708 108static void do_disk_add_remove(struct work_struct *work);
dc950861 109static void virthba_serverdown_complete(struct work_struct *work);
d9c5607e 110static ssize_t info_debugfs_read(struct file *file, char __user *buf,
836600fa 111 size_t len, loff_t *offset);
79014eb1 112static ssize_t enable_ints_write(struct file *file,
836600fa
KD
113 const char __user *buffer, size_t count,
114 loff_t *ppos);
dc950861 115
dc950861
KC
116/*****************************************************/
117/* Globals */
118/*****************************************************/
119
a8d7f21d 120static int rsltq_wait_usecs = 4000; /* Default 4ms */
366cf71a 121static unsigned int max_buff_len;
dc950861
KC
122
123/* Module options */
a8d7f21d 124static char *virthba_options = "NONE";
dc950861
KC
125
126static const struct pci_device_id virthba_id_table[] = {
127 {PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_VIRTHBA)},
128 {0},
129};
130
131/* export virthba_id_table */
132MODULE_DEVICE_TABLE(pci, virthba_id_table);
133
134static struct workqueue_struct *virthba_serverdown_workqueue;
135
136static struct virtpci_driver virthba_driver = {
137 .name = "uisvirthba",
138 .version = VERSION,
139 .vertag = NULL,
dc950861
KC
140 .id_table = virthba_id_table,
141 .probe = virthba_probe,
142 .remove = virthba_remove,
143 .resume = virthba_serverup,
144 .suspend = virthba_serverdown
145};
146
147/* The Send and Recive Buffers of the IO Queue may both be full */
148#define MAX_PENDING_REQUESTS (MIN_NUMSIGNALS*2)
149#define INTERRUPT_VECTOR_MASK 0x3F
150
151struct scsipending {
152 char cmdtype; /* Type of pointer that is being stored */
153 void *sent; /* The Data being tracked */
154 /* struct scsi_cmnd *type for virthba_queue_command */
155 /* struct uiscmdrsp *type for management commands */
156};
157
158#define VIRTHBA_ERROR_COUNT 30
159#define IOS_ERROR_THRESHOLD 1000
160struct virtdisk_info {
b3c55b13
BR
161 u32 valid;
162 u32 channel, id, lun; /* Disk Path */
dc950861
KC
163 atomic_t ios_threshold;
164 atomic_t error_count;
165 struct virtdisk_info *next;
166};
1cc598c7 167
dc950861
KC
168/* Each Scsi_Host has a host_data area that contains this struct. */
169struct virthba_info {
170 struct Scsi_Host *scsihost;
171 struct virtpci_dev *virtpcidev;
172 struct list_head dev_info_list;
173 struct chaninfo chinfo;
4eddbf13 174 struct irq_info intr; /* use recvInterrupt info to receive
dc950861
KC
175 interrupts when IOs complete */
176 int interrupt_vector;
177 struct scsipending pending[MAX_PENDING_REQUESTS]; /* Tracks the requests
178 that have been */
179 /* forwarded to the IOVM and haven't returned yet */
180 unsigned int nextinsert; /* Start search for next pending
181 free slot here */
182 spinlock_t privlock;
183 bool serverdown;
184 bool serverchangingstate;
185 unsigned long long acquire_failed_cnt;
186 unsigned long long interrupts_rcvd;
187 unsigned long long interrupts_notme;
188 unsigned long long interrupts_disabled;
189 struct work_struct serverdown_completion;
5fc0229a 190 u64 __iomem *flags_addr;
dc950861
KC
191 atomic_t interrupt_rcvd;
192 wait_queue_head_t rsp_queue;
193 struct virtdisk_info head;
194};
195
83afa349 196/* Work Data for dar_work_queue */
dc950861 197struct diskaddremove {
c242233e 198 u8 add; /* 0-remove, 1-add */
dc950861 199 struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
b3c55b13 200 u32 channel, id, lun; /* Disk Path */
dc950861
KC
201 struct diskaddremove *next;
202};
203
204#define virtpci_dev_to_virthba_virthba_get_info(d) \
205 container_of(d, struct virthba_info, virtpcidev)
206
207static DEVICE_ATTRIBUTE *virthba_shost_attrs[];
208static struct scsi_host_template virthba_driver_template = {
209 .name = "Unisys Virtual HBA",
dc950861
KC
210 .info = virthba_get_info,
211 .ioctl = virthba_ioctl,
212 .queuecommand = virthba_queue_command,
213 .eh_abort_handler = virthba_abort_handler,
214 .eh_device_reset_handler = virthba_device_reset_handler,
215 .eh_bus_reset_handler = virthba_bus_reset_handler,
216 .eh_host_reset_handler = virthba_host_reset_handler,
217 .shost_attrs = virthba_shost_attrs,
218
219#define VIRTHBA_MAX_CMNDS 128
220 .can_queue = VIRTHBA_MAX_CMNDS,
221 .sg_tablesize = 64, /* largest number of address/length pairs */
222 .this_id = -1,
223 .slave_alloc = virthba_slave_alloc,
224 .slave_configure = virthba_slave_configure,
225 .slave_destroy = virthba_slave_destroy,
226 .use_clustering = ENABLE_CLUSTERING,
227};
228
229struct virthba_devices_open {
230 struct virthba_info *virthbainfo;
231};
232
d9c5607e
EA
233static const struct file_operations debugfs_info_fops = {
234 .read = info_debugfs_read,
235};
236
79014eb1
EA
237static const struct file_operations debugfs_enable_ints_fops = {
238 .write = enable_ints_write,
239};
240
d9c5607e
EA
241/*****************************************************/
242/* Structs */
243/*****************************************************/
244
dc950861
KC
245#define VIRTHBASOPENMAX 1
246/* array of open devices maintained by open() and close(); */
366cf71a 247static struct virthba_devices_open virthbas_open[VIRTHBASOPENMAX];
d9c5607e 248static struct dentry *virthba_debugfs_dir;
dc950861
KC
249
250/*****************************************************/
251/* Local Functions */
252/*****************************************************/
253static int
254add_scsipending_entry(struct virthba_info *vhbainfo, char cmdtype, void *new)
255{
256 unsigned long flags;
257 int insert_location;
258
259 spin_lock_irqsave(&vhbainfo->privlock, flags);
260 insert_location = vhbainfo->nextinsert;
5af3b098 261 while (vhbainfo->pending[insert_location].sent) {
dc950861 262 insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
396beed6 263 if (insert_location == (int)vhbainfo->nextinsert) {
dc950861
KC
264 spin_unlock_irqrestore(&vhbainfo->privlock, flags);
265 return -1;
266 }
267 }
268
269 vhbainfo->pending[insert_location].cmdtype = cmdtype;
270 vhbainfo->pending[insert_location].sent = new;
271 vhbainfo->nextinsert = (insert_location + 1) % MAX_PENDING_REQUESTS;
272 spin_unlock_irqrestore(&vhbainfo->privlock, flags);
273
274 return insert_location;
275}
276
277static unsigned int
278add_scsipending_entry_with_wait(struct virthba_info *vhbainfo, char cmdtype,
279 void *new)
280{
281 int insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
282
283 while (insert_location == -1) {
dc950861
KC
284 set_current_state(TASK_INTERRUPTIBLE);
285 schedule_timeout(msecs_to_jiffies(10));
286 insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
287 }
288
396beed6 289 return (unsigned int)insert_location;
dc950861
KC
290}
291
292static void *
293del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
294{
295 unsigned long flags;
296 void *sent = NULL;
297
0aca7844 298 if (del < MAX_PENDING_REQUESTS) {
dc950861 299 spin_lock_irqsave(&vhbainfo->privlock, flags);
dc950861
KC
300 sent = vhbainfo->pending[del].sent;
301
302 vhbainfo->pending[del].cmdtype = 0;
303 vhbainfo->pending[del].sent = NULL;
304 spin_unlock_irqrestore(&vhbainfo->privlock, flags);
305 }
306
307 return sent;
308}
309
83afa349
KD
310/* dar_work_queue (Disk Add/Remove) */
311static struct work_struct dar_work_queue;
312static struct diskaddremove *dar_work_queue_head;
313static spinlock_t dar_work_queue_lock;
314static unsigned short dar_work_queue_sched;
dc950861 315#define QUEUE_DISKADDREMOVE(dar) { \
83afa349
KD
316 spin_lock_irqsave(&dar_work_queue_lock, flags); \
317 if (!dar_work_queue_head) { \
318 dar_work_queue_head = dar; \
dc950861
KC
319 dar->next = NULL; \
320 } \
321 else { \
83afa349
KD
322 dar->next = dar_work_queue_head; \
323 dar_work_queue_head = dar; \
dc950861 324 } \
83afa349
KD
325 if (!dar_work_queue_sched) { \
326 schedule_work(&dar_work_queue); \
327 dar_work_queue_sched = 1; \
dc950861 328 } \
83afa349 329 spin_unlock_irqrestore(&dar_work_queue_lock, flags); \
dc950861
KC
330}
331
332static inline void
b6e0a708 333send_disk_add_remove(struct diskaddremove *dar)
dc950861
KC
334{
335 struct scsi_device *sdev;
336 int error;
337
338 sdev = scsi_device_lookup(dar->shost, dar->channel, dar->id, dar->lun);
339 if (sdev) {
340 if (!(dar->add))
341 scsi_remove_device(sdev);
342 } else if (dar->add) {
343 error =
344 scsi_add_device(dar->shost, dar->channel, dar->id,
345 dar->lun);
0aca7844 346 }
dc950861
KC
347 kfree(dar);
348}
349
350/*****************************************************/
83afa349 351/* dar_work_queue Handler Thread */
dc950861
KC
352/*****************************************************/
353static void
b6e0a708 354do_disk_add_remove(struct work_struct *work)
dc950861
KC
355{
356 struct diskaddremove *dar;
357 struct diskaddremove *tmphead;
358 int i = 0;
359 unsigned long flags;
360
83afa349
KD
361 spin_lock_irqsave(&dar_work_queue_lock, flags);
362 tmphead = dar_work_queue_head;
363 dar_work_queue_head = NULL;
364 dar_work_queue_sched = 0;
365 spin_unlock_irqrestore(&dar_work_queue_lock, flags);
dc950861
KC
366 while (tmphead) {
367 dar = tmphead;
368 tmphead = dar->next;
b6e0a708 369 send_disk_add_remove(dar);
dc950861
KC
370 i++;
371 }
372}
373
374/*****************************************************/
83afa349 375/* Routine to add entry to dar_work_queue */
dc950861
KC
376/*****************************************************/
377static void
378process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
379{
380 struct diskaddremove *dar;
381 unsigned long flags;
382
c7553dad 383 dar = kzalloc(sizeof(*dar), GFP_ATOMIC);
dc950861 384 if (dar) {
dc950861
KC
385 dar->add = cmdrsp->disknotify.add;
386 dar->shost = shost;
387 dar->channel = cmdrsp->disknotify.channel;
388 dar->id = cmdrsp->disknotify.id;
389 dar->lun = cmdrsp->disknotify.lun;
390 QUEUE_DISKADDREMOVE(dar);
dc950861
KC
391 }
392}
393
394/*****************************************************/
395/* Probe Remove Functions */
396/*****************************************************/
a8d7f21d 397static irqreturn_t
347d0560 398virthba_isr(int irq, void *dev_id)
dc950861 399{
396beed6 400 struct virthba_info *virthbainfo = (struct virthba_info *)dev_id;
347d0560 401 struct channel_header __iomem *channel_header;
e0fed862 402 struct signal_queue_header __iomem *pqhdr;
5fc0229a 403 u64 mask;
dc950861
KC
404 unsigned long long rc1;
405
5af3b098 406 if (!virthbainfo)
dc950861
KC
407 return IRQ_NONE;
408 virthbainfo->interrupts_rcvd++;
347d0560
BR
409 channel_header = virthbainfo->chinfo.queueinfo->chan;
410 if (((readq(&channel_header->features)
45104bf9 411 & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) &&
347d0560 412 ((readq(&channel_header->features) &
a8d7f21d 413 ULTRA_IO_DRIVER_DISABLES_INTS) !=
dc950861
KC
414 0)) {
415 virthbainfo->interrupts_disabled++;
416 mask = ~ULTRA_CHANNEL_ENABLE_INTS;
17f5e491 417 rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask);
dc950861 418 }
347d0560 419 if (spar_signalqueue_empty(channel_header, IOCHAN_FROM_IOPART)) {
dc950861
KC
420 virthbainfo->interrupts_notme++;
421 return IRQ_NONE;
422 }
e0fed862 423 pqhdr = (struct signal_queue_header __iomem *)
347d0560
BR
424 ((char __iomem *)channel_header +
425 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
153cf710
BR
426 writeq(readq(&pqhdr->num_irq_received) + 1,
427 &pqhdr->num_irq_received);
dc950861
KC
428 atomic_set(&virthbainfo->interrupt_rcvd, 1);
429 wake_up_interruptible(&virthbainfo->rsp_queue);
430 return IRQ_HANDLED;
431}
432
433static int
434virthba_probe(struct virtpci_dev *virtpcidev, const struct pci_device_id *id)
435{
436 int error;
437 struct Scsi_Host *scsihost;
438 struct virthba_info *virthbainfo;
439 int rsp;
440 int i;
347d0560 441 irq_handler_t handler = virthba_isr;
17893770 442 struct channel_header __iomem *channel_header;
e0fed862 443 struct signal_queue_header __iomem *pqhdr;
5fc0229a 444 u64 mask;
dc950861 445
dc950861
KC
446 POSTCODE_LINUX_2(VHBA_PROBE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
447 /* call scsi_host_alloc to register a scsi host adapter
448 * instance - this virthba that has just been created is an
449 * instance of a scsi host adapter. This scsi_host_alloc
450 * function allocates a new Scsi_Host struct & performs basic
659688a5 451 * initialization. The host is not published to the scsi
dc950861
KC
452 * midlayer until scsi_add_host is called.
453 */
dc950861
KC
454
455 /* arg 2 passed in length of extra space we want allocated
456 * with scsi_host struct for our own use scsi_host_alloc
457 * assign host_no
458 */
459 scsihost = scsi_host_alloc(&virthba_driver_template,
460 sizeof(struct virthba_info));
5af3b098 461 if (!scsihost)
dc950861
KC
462 return -ENODEV;
463
dc950861
KC
464 scsihost->this_id = UIS_MAGIC_VHBA;
465 /* linux treats max-channel differently than max-id & max-lun.
466 * In the latter cases, those two values result in 0 to max-1
467 * (inclusive) being scanned. But in the case of channels, the
468 * scan is 0 to max (inclusive); so we will subtract one from
469 * the max-channel value.
470 */
396beed6
KD
471 scsihost->max_channel = (unsigned)virtpcidev->scsi.max.max_channel;
472 scsihost->max_id = (unsigned)virtpcidev->scsi.max.max_id;
473 scsihost->max_lun = (unsigned)virtpcidev->scsi.max.max_lun;
474 scsihost->cmd_per_lun = (unsigned)virtpcidev->scsi.max.cmd_per_lun;
dc950861 475 scsihost->max_sectors =
396beed6 476 (unsigned short)(virtpcidev->scsi.max.max_io_size >> 9);
dc950861 477 scsihost->sg_tablesize =
396beed6 478 (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
dc950861
KC
479 if (scsihost->sg_tablesize > MAX_PHYS_INFO)
480 scsihost->sg_tablesize = MAX_PHYS_INFO;
dc950861 481
dc950861
KC
482 /* this creates "host%d" in sysfs. If 2nd argument is NULL,
483 * then this generic /sys/devices/platform/host? device is
484 * created and /sys/scsi_host/host? ->
485 * /sys/devices/platform/host? If 2nd argument is not NULL,
486 * then this generic /sys/devices/<path>/host? is created and
487 * host? points to that device instead.
488 */
489 error = scsi_add_host(scsihost, &virtpcidev->generic_dev);
490 if (error) {
dc950861
KC
491 POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
492 /* decr refcount on scsihost which was incremented by
493 * scsi_add_host so the scsi_host gets deleted
494 */
495 scsi_host_put(scsihost);
496 return -ENODEV;
497 }
498
396beed6 499 virthbainfo = (struct virthba_info *)scsihost->hostdata;
dc950861
KC
500 memset(virthbainfo, 0, sizeof(struct virthba_info));
501 for (i = 0; i < VIRTHBASOPENMAX; i++) {
5af3b098 502 if (!virthbas_open[i].virthbainfo) {
366cf71a 503 virthbas_open[i].virthbainfo = virthbainfo;
dc950861
KC
504 break;
505 }
506 }
507 virthbainfo->interrupt_vector = -1;
508 virthbainfo->chinfo.queueinfo = &virtpcidev->queueinfo;
509 virthbainfo->virtpcidev = virtpcidev;
510 spin_lock_init(&virthbainfo->chinfo.insertlock);
511
dc950861
KC
512 init_waitqueue_head(&virthbainfo->rsp_queue);
513 spin_lock_init(&virthbainfo->privlock);
514 memset(&virthbainfo->pending, 0, sizeof(virthbainfo->pending));
515 virthbainfo->serverdown = false;
516 virthbainfo->serverchangingstate = false;
517
518 virthbainfo->intr = virtpcidev->intr;
519 /* save of host within virthba_info */
520 virthbainfo->scsihost = scsihost;
521
522 /* save of host within virtpci_dev */
523 virtpcidev->scsi.scsihost = scsihost;
524
525 /* Setup workqueue for serverdown messages */
526 INIT_WORK(&virthbainfo->serverdown_completion,
527 virthba_serverdown_complete);
528
a8a31f61 529 writeq(readq(&virthbainfo->chinfo.queueinfo->chan->features) |
a8d7f21d 530 ULTRA_IO_CHANNEL_IS_POLLING,
a8a31f61 531 &virthbainfo->chinfo.queueinfo->chan->features);
dc950861 532 /* start thread that will receive scsicmnd responses */
dc950861 533
17893770 534 channel_header = virthbainfo->chinfo.queueinfo->chan;
e0fed862 535 pqhdr = (struct signal_queue_header __iomem *)
17893770
BR
536 ((char __iomem *)channel_header +
537 readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
153cf710 538 virthbainfo->flags_addr = &pqhdr->features;
dc950861
KC
539
540 if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
541 process_incoming_rsps,
542 virthbainfo, "vhba_incoming")) {
dc950861
KC
543 /* decr refcount on scsihost which was incremented by
544 * scsi_add_host so the scsi_host gets deleted
545 */
546 POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
547 scsi_host_put(scsihost);
548 return -ENODEV;
549 }
dc950861 550 virthbainfo->interrupt_vector =
af3286bd 551 virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK;
dc950861
KC
552 rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED,
553 scsihost->hostt->name, virthbainfo);
554 if (rsp != 0) {
dc950861
KC
555 virthbainfo->interrupt_vector = -1;
556 POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
557 } else {
56215add 558 u64 __iomem *features_addr =
a8a31f61 559 &virthbainfo->chinfo.queueinfo->chan->features;
dc950861
KC
560 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
561 ULTRA_IO_DRIVER_DISABLES_INTS);
56215add 562 uisqueue_interlocked_and(features_addr, mask);
dc950861 563 mask = ULTRA_IO_DRIVER_ENABLES_INTS;
56215add 564 uisqueue_interlocked_or(features_addr, mask);
dc950861
KC
565 rsltq_wait_usecs = 4000000;
566 }
567
dc950861 568 scsi_scan_host(scsihost);
dc950861 569
dc950861
KC
570 POSTCODE_LINUX_2(VHBA_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO);
571 return 0;
572}
573
574static void
575virthba_remove(struct virtpci_dev *virtpcidev)
576{
577 struct virthba_info *virthbainfo;
578 struct Scsi_Host *scsihost =
396beed6 579 (struct Scsi_Host *)virtpcidev->scsi.scsihost;
dc950861 580
396beed6 581 virthbainfo = (struct virthba_info *)scsihost->hostdata;
dc950861
KC
582 if (virthbainfo->interrupt_vector != -1)
583 free_irq(virthbainfo->interrupt_vector, virthbainfo);
dc950861 584
dc950861
KC
585 scsi_remove_host(scsihost);
586
dc950861
KC
587 uisthread_stop(&virthbainfo->chinfo.threadinfo);
588
dc950861
KC
589 /* decr refcount on scsihost which was incremented by
590 * scsi_add_host so the scsi_host gets deleted
591 */
592 scsi_host_put(scsihost);
dc950861
KC
593}
594
595static int
c8cf5d07 596forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
dc950861
KC
597 struct Scsi_Host *scsihost,
598 struct uisscsi_dest *vdest)
599{
600 struct uiscmdrsp *cmdrsp;
601 struct virthba_info *virthbainfo =
396beed6 602 (struct virthba_info *)scsihost->hostdata;
dc950861
KC
603 int notifyresult = 0xffff;
604 wait_queue_head_t notifyevent;
605
4de57acb 606 if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
dc950861 607 return FAILED;
dc950861 608
a3acc83a 609 cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
5af3b098 610 if (!cmdrsp)
edff162c 611 return FAILED; /* reject */
dc950861
KC
612
613 init_waitqueue_head(&notifyevent);
614
615 /* issue VDISK_MGMT_CMD
616 * set type to command - as opposed to task mgmt
617 */
618 cmdrsp->cmdtype = CMD_VDISKMGMT_TYPE;
619 /* specify the event that has to be triggered when this cmd is
620 * complete
621 */
396beed6
KD
622 cmdrsp->vdiskmgmt.notify = (void *)&notifyevent;
623 cmdrsp->vdiskmgmt.notifyresult = (void *)&notifyresult;
dc950861
KC
624
625 /* save destination */
626 cmdrsp->vdiskmgmt.vdisktype = vdiskcmdtype;
627 cmdrsp->vdiskmgmt.vdest.channel = vdest->channel;
628 cmdrsp->vdiskmgmt.vdest.id = vdest->id;
629 cmdrsp->vdiskmgmt.vdest.lun = vdest->lun;
630 cmdrsp->vdiskmgmt.scsicmd =
396beed6 631 (void *)(uintptr_t)
dc950861 632 add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE,
396beed6 633 (void *)cmdrsp);
dc950861
KC
634
635 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
636 cmdrsp, IOCHAN_TO_IOPART,
637 &virthbainfo->chinfo.insertlock,
396beed6 638 DONT_ISSUE_INTERRUPT, (u64)NULL,
dc950861 639 OK_TO_WAIT, "vhba");
dc950861 640 wait_event(notifyevent, notifyresult != 0xffff);
dc950861
KC
641 kfree(cmdrsp);
642 return SUCCESS;
643}
644
645/*****************************************************/
646/* Scsi Host support functions */
647/*****************************************************/
648
649static int
63f06ba1
BR
650forward_taskmgmt_command(enum task_mgmt_types tasktype,
651 struct scsi_device *scsidev)
dc950861
KC
652{
653 struct uiscmdrsp *cmdrsp;
654 struct virthba_info *virthbainfo =
396beed6 655 (struct virthba_info *)scsidev->host->hostdata;
dc950861
KC
656 int notifyresult = 0xffff;
657 wait_queue_head_t notifyevent;
658
4de57acb 659 if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
dc950861 660 return FAILED;
dc950861 661
a3acc83a 662 cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
5af3b098
BR
663 if (!cmdrsp)
664 return FAILED; /* reject */
dc950861
KC
665
666 init_waitqueue_head(&notifyevent);
667
668 /* issue TASK_MGMT_ABORT_TASK */
669 /* set type to command - as opposed to task mgmt */
670 cmdrsp->cmdtype = CMD_SCSITASKMGMT_TYPE;
671 /* specify the event that has to be triggered when this */
672 /* cmd is complete */
396beed6
KD
673 cmdrsp->scsitaskmgmt.notify = (void *)&notifyevent;
674 cmdrsp->scsitaskmgmt.notifyresult = (void *)&notifyresult;
dc950861
KC
675
676 /* save destination */
677 cmdrsp->scsitaskmgmt.tasktype = tasktype;
678 cmdrsp->scsitaskmgmt.vdest.channel = scsidev->channel;
679 cmdrsp->scsitaskmgmt.vdest.id = scsidev->id;
680 cmdrsp->scsitaskmgmt.vdest.lun = scsidev->lun;
681 cmdrsp->scsitaskmgmt.scsicmd =
396beed6 682 (void *)(uintptr_t)
dc950861
KC
683 add_scsipending_entry_with_wait(virthbainfo,
684 CMD_SCSITASKMGMT_TYPE,
396beed6 685 (void *)cmdrsp);
dc950861
KC
686
687 uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
688 cmdrsp, IOCHAN_TO_IOPART,
689 &virthbainfo->chinfo.insertlock,
396beed6 690 DONT_ISSUE_INTERRUPT, (u64)NULL,
dc950861 691 OK_TO_WAIT, "vhba");
dc950861 692 wait_event(notifyevent, notifyresult != 0xffff);
dc950861
KC
693 kfree(cmdrsp);
694 return SUCCESS;
695}
696
697/* The abort handler returns SUCCESS if it has succeeded to make LLDD
698 * and all related hardware forget about the scmd.
699 */
700static int
701virthba_abort_handler(struct scsi_cmnd *scsicmd)
702{
703 /* issue TASK_MGMT_ABORT_TASK */
704 struct scsi_device *scsidev;
705 struct virtdisk_info *vdisk;
706
707 scsidev = scsicmd->device;
396beed6 708 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
dc950861 709 vdisk->next; vdisk = vdisk->next) {
45104bf9
KD
710 if ((scsidev->channel == vdisk->channel) &&
711 (scsidev->id == vdisk->id) &&
712 (scsidev->lun == vdisk->lun)) {
dc950861
KC
713 if (atomic_read(&vdisk->error_count) <
714 VIRTHBA_ERROR_COUNT) {
715 atomic_inc(&vdisk->error_count);
716 POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
717 POSTCODE_SEVERITY_INFO);
718 } else
719 atomic_set(&vdisk->ios_threshold,
720 IOS_ERROR_THRESHOLD);
721 }
722 }
723 return forward_taskmgmt_command(TASK_MGMT_ABORT_TASK, scsicmd->device);
724}
725
726static int
727virthba_bus_reset_handler(struct scsi_cmnd *scsicmd)
728{
729 /* issue TASK_MGMT_TARGET_RESET for each target on the bus */
730 struct scsi_device *scsidev;
731 struct virtdisk_info *vdisk;
732
733 scsidev = scsicmd->device;
396beed6 734 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
dc950861 735 vdisk->next; vdisk = vdisk->next) {
45104bf9
KD
736 if ((scsidev->channel == vdisk->channel) &&
737 (scsidev->id == vdisk->id) &&
738 (scsidev->lun == vdisk->lun)) {
dc950861
KC
739 if (atomic_read(&vdisk->error_count) <
740 VIRTHBA_ERROR_COUNT) {
741 atomic_inc(&vdisk->error_count);
742 POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
743 POSTCODE_SEVERITY_INFO);
744 } else
745 atomic_set(&vdisk->ios_threshold,
746 IOS_ERROR_THRESHOLD);
747 }
748 }
749 return forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsicmd->device);
750}
751
752static int
753virthba_device_reset_handler(struct scsi_cmnd *scsicmd)
754{
755 /* issue TASK_MGMT_LUN_RESET */
756 struct scsi_device *scsidev;
757 struct virtdisk_info *vdisk;
758
759 scsidev = scsicmd->device;
396beed6 760 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
dc950861 761 vdisk->next; vdisk = vdisk->next) {
45104bf9
KD
762 if ((scsidev->channel == vdisk->channel) &&
763 (scsidev->id == vdisk->id) &&
764 (scsidev->lun == vdisk->lun)) {
dc950861
KC
765 if (atomic_read(&vdisk->error_count) <
766 VIRTHBA_ERROR_COUNT) {
767 atomic_inc(&vdisk->error_count);
768 POSTCODE_LINUX_2(VHBA_COMMAND_HANDLER_PC,
769 POSTCODE_SEVERITY_INFO);
770 } else
771 atomic_set(&vdisk->ios_threshold,
772 IOS_ERROR_THRESHOLD);
773 }
774 }
775 return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsicmd->device);
776}
777
778static int
779virthba_host_reset_handler(struct scsi_cmnd *scsicmd)
780{
781 /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
dc950861
KC
782 return SUCCESS;
783}
784
785static char virthba_get_info_str[256];
786
787static const char *
788virthba_get_info(struct Scsi_Host *shp)
789{
790 /* Return version string */
791 sprintf(virthba_get_info_str, "virthba, version %s\n", VIRTHBA_VERSION);
792 return virthba_get_info_str;
793}
794
795static int
796virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
797{
dc950861
KC
798 return -EINVAL;
799}
800
801/* This returns SCSI_MLQUEUE_DEVICE_BUSY if the signal queue to IOpart
802 * is full.
803 */
804static int
805virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
806 void (*virthba_cmnd_done)(struct scsi_cmnd *))
807{
808 struct scsi_device *scsidev = scsicmd->device;
809 int insert_location;
810 unsigned char op;
811 unsigned char *cdb = scsicmd->cmnd;
812 struct Scsi_Host *scsihost = scsidev->host;
813 struct uiscmdrsp *cmdrsp;
814 unsigned int i;
815 struct virthba_info *virthbainfo =
396beed6 816 (struct virthba_info *)scsihost->hostdata;
dc950861
KC
817 struct scatterlist *sg = NULL;
818 struct scatterlist *sgl = NULL;
819 int sg_failed = 0;
820
4de57acb 821 if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
dc950861 822 return SCSI_MLQUEUE_DEVICE_BUSY;
a3acc83a 823 cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
5af3b098 824 if (!cmdrsp)
dc950861 825 return 1; /* reject the command */
dc950861
KC
826
827 /* now saving everything we need from scsi_cmd into cmdrsp
828 * before we queue cmdrsp set type to command - as opposed to
829 * task mgmt
830 */
831 cmdrsp->cmdtype = CMD_SCSI_TYPE;
832 /* save the pending insertion location. Deletion from pending
833 * will return the scsicmd pointer for completion
834 */
835 insert_location =
396beed6 836 add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *)scsicmd);
dc950861 837 if (insert_location != -1) {
396beed6 838 cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location;
dc950861 839 } else {
dc950861
KC
840 kfree(cmdrsp);
841 return SCSI_MLQUEUE_DEVICE_BUSY;
842 }
843 /* save done function that we have call when cmd is complete */
844 scsicmd->scsi_done = virthba_cmnd_done;
845 /* save destination */
846 cmdrsp->scsi.vdest.channel = scsidev->channel;
847 cmdrsp->scsi.vdest.id = scsidev->id;
848 cmdrsp->scsi.vdest.lun = scsidev->lun;
849 /* save datadir */
850 cmdrsp->scsi.data_dir = scsicmd->sc_data_direction;
851 memcpy(cmdrsp->scsi.cmnd, cdb, MAX_CMND_SIZE);
852
853 cmdrsp->scsi.bufflen = scsi_bufflen(scsicmd);
854
855 /* keep track of the max buffer length so far. */
366cf71a
KD
856 if (cmdrsp->scsi.bufflen > max_buff_len)
857 max_buff_len = cmdrsp->scsi.bufflen;
dc950861
KC
858
859 if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) {
396beed6 860 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
dc950861
KC
861 kfree(cmdrsp);
862 return 1; /* reject the command */
863 }
864
865 /* This is what we USED to do when we assumed we were running */
866 /* uissd & virthba on the same Linux system. */
867 /* cmdrsp->scsi.buffer = scsicmd->request_buffer; */
868 /* The following code does NOT make that assumption. */
869 /* convert buffer to phys information */
870 if (scsi_sg_count(scsicmd) == 0) {
871 if (scsi_bufflen(scsicmd) > 0) {
dc950861
KC
872 BUG_ON(scsi_sg_count(scsicmd) == 0);
873 }
dc950861
KC
874 } else {
875 /* buffer is scatterlist - copy it out */
876 sgl = scsi_sglist(scsicmd);
877
878 for_each_sg(sgl, sg, scsi_sg_count(scsicmd), i) {
dc950861
KC
879 cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
880 cmdrsp->scsi.gpi_list[i].length = sg->length;
dc950861
KC
881 }
882
883 if (sg_failed) {
dc950861
KC
884 /* BUG(); ***** For now, let it fail in uissd
885 * if it is a problem, as it might just
886 * work
887 */
888 }
889
890 cmdrsp->scsi.guest_phys_entries = scsi_sg_count(scsicmd);
891 }
892
893 op = cdb[0];
894 i = uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
895 cmdrsp, IOCHAN_TO_IOPART,
896 &virthbainfo->chinfo.
897 insertlock,
898 DONT_ISSUE_INTERRUPT,
396beed6 899 (u64)NULL, DONT_WAIT, "vhba");
dc950861
KC
900 if (i == 0) {
901 /* queue must be full - and we said don't wait - return busy */
dc950861 902 kfree(cmdrsp);
396beed6 903 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
dc950861
KC
904 return SCSI_MLQUEUE_DEVICE_BUSY;
905 }
906
907 /* we're done with cmdrsp space - data from it has been copied
908 * into channel - free it now.
909 */
910 kfree(cmdrsp);
911 return 0; /* non-zero implies host/device is busy */
912}
913
914static int
915virthba_slave_alloc(struct scsi_device *scsidev)
916{
917 /* this called by the midlayer before scan for new devices -
fb90c609 918 * LLD can alloc any struct & do init if needed.
dc950861
KC
919 */
920 struct virtdisk_info *vdisk;
921 struct virtdisk_info *tmpvdisk;
922 struct virthba_info *virthbainfo;
396beed6 923 struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
dc950861 924
396beed6 925 virthbainfo = (struct virthba_info *)scsihost->hostdata;
0aca7844 926 if (!virthbainfo)
dc950861 927 return 0; /* even though we errored, treat as success */
0aca7844 928
dc950861
KC
929 for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
930 if (vdisk->next->valid &&
931 (vdisk->next->channel == scsidev->channel) &&
932 (vdisk->next->id == scsidev->id) &&
933 (vdisk->next->lun == scsidev->lun))
934 return 0;
935 }
c7553dad 936 tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
edff162c 937 if (!tmpvdisk)
dc950861 938 return 0;
97a84f12 939
dc950861
KC
940 tmpvdisk->channel = scsidev->channel;
941 tmpvdisk->id = scsidev->id;
942 tmpvdisk->lun = scsidev->lun;
943 tmpvdisk->valid = 1;
944 vdisk->next = tmpvdisk;
945 return 0; /* success */
946}
947
948static int
949virthba_slave_configure(struct scsi_device *scsidev)
950{
951 return 0; /* success */
952}
953
954static void
955virthba_slave_destroy(struct scsi_device *scsidev)
956{
957 /* midlevel calls this after device has been quiesced and
958 * before it is to be deleted.
959 */
960 struct virtdisk_info *vdisk, *delvdisk;
961 struct virthba_info *virthbainfo;
396beed6 962 struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
dc950861 963
396beed6 964 virthbainfo = (struct virthba_info *)scsihost->hostdata;
dc950861
KC
965 for (vdisk = &virthbainfo->head; vdisk->next; vdisk = vdisk->next) {
966 if (vdisk->next->valid &&
967 (vdisk->next->channel == scsidev->channel) &&
968 (vdisk->next->id == scsidev->id) &&
969 (vdisk->next->lun == scsidev->lun)) {
970 delvdisk = vdisk->next;
971 vdisk->next = vdisk->next->next;
972 kfree(delvdisk);
973 return;
974 }
975 }
dc950861
KC
976}
977
978/*****************************************************/
979/* Scsi Cmnd support thread */
980/*****************************************************/
981
982static void
983do_scsi_linuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
984{
985 struct virtdisk_info *vdisk;
986 struct scsi_device *scsidev;
987 struct sense_data *sd;
988
989 scsidev = scsicmd->device;
990 memcpy(scsicmd->sense_buffer, cmdrsp->scsi.sensebuf, MAX_SENSE_SIZE);
396beed6 991 sd = (struct sense_data *)scsicmd->sense_buffer;
dc950861
KC
992
993 /* Do not log errors for disk-not-present inquiries */
994 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
995 (host_byte(cmdrsp->scsi.linuxstat) == DID_NO_CONNECT) &&
996 (cmdrsp->scsi.addlstat == ADDL_SEL_TIMEOUT))
997 return;
998
999 /* Okay see what our error_count is here.... */
396beed6 1000 for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
dc950861 1001 vdisk->next; vdisk = vdisk->next) {
45104bf9
KD
1002 if ((scsidev->channel != vdisk->channel) ||
1003 (scsidev->id != vdisk->id) ||
1004 (scsidev->lun != vdisk->lun))
dc950861
KC
1005 continue;
1006
1007 if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) {
1008 atomic_inc(&vdisk->error_count);
dc950861
KC
1009 atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
1010 }
1011 }
1012}
1013
1014static void
1015do_scsi_nolinuxstat(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1016{
1017 struct scsi_device *scsidev;
1018 unsigned char buf[36];
1019 struct scatterlist *sg;
1020 unsigned int i;
1021 char *thispage;
1022 char *thispage_orig;
1023 int bufind = 0;
1024 struct virtdisk_info *vdisk;
1025
1026 scsidev = scsicmd->device;
45104bf9
KD
1027 if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
1028 (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
dc950861
KC
1029 if (cmdrsp->scsi.no_disk_result == 0)
1030 return;
1031
1032 /* Linux scsi code is weird; it wants
1033 * a device at Lun 0 to issue report
1034 * luns, but we don't want a disk
1035 * there so we'll present a processor
1036 * there. */
1037 SET_NO_DISK_INQUIRY_RESULT(buf, cmdrsp->scsi.bufflen,
1038 scsidev->lun,
1039 DEV_DISK_CAPABLE_NOT_PRESENT,
1040 DEV_NOT_CAPABLE);
1041
1042 if (scsi_sg_count(scsicmd) == 0) {
1043 if (scsi_bufflen(scsicmd) > 0) {
dc950861
KC
1044 BUG_ON(scsi_sg_count(scsicmd) ==
1045 0);
1046 }
1047 memcpy(scsi_sglist(scsicmd), buf,
1048 cmdrsp->scsi.bufflen);
1049 return;
1050 }
1051
1052 sg = scsi_sglist(scsicmd);
1053 for (i = 0; i < scsi_sg_count(scsicmd); i++) {
dc950861 1054 thispage_orig = kmap_atomic(sg_page(sg + i));
396beed6 1055 thispage = (void *)((unsigned long)thispage_orig |
dc950861
KC
1056 sg[i].offset);
1057 memcpy(thispage, buf + bufind, sg[i].length);
1058 kunmap_atomic(thispage_orig);
1059 bufind += sg[i].length;
1060 }
1061 } else {
dc950861
KC
1062 vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
1063 for ( ; vdisk->next; vdisk = vdisk->next) {
45104bf9
KD
1064 if ((scsidev->channel != vdisk->channel) ||
1065 (scsidev->id != vdisk->id) ||
1066 (scsidev->lun != vdisk->lun))
dc950861
KC
1067 continue;
1068
1069 if (atomic_read(&vdisk->ios_threshold) > 0) {
1070 atomic_dec(&vdisk->ios_threshold);
1071 if (atomic_read(&vdisk->ios_threshold) == 0) {
dc950861
KC
1072 atomic_set(&vdisk->error_count, 0);
1073 }
1074 }
1075 }
1076 }
1077}
1078
1079static void
1080complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1081{
dc950861
KC
1082 /* take what we need out of cmdrsp and complete the scsicmd */
1083 scsicmd->result = cmdrsp->scsi.linuxstat;
1084 if (cmdrsp->scsi.linuxstat)
1085 do_scsi_linuxstat(cmdrsp, scsicmd);
1086 else
1087 do_scsi_nolinuxstat(cmdrsp, scsicmd);
1088
4de57acb 1089 if (scsicmd->scsi_done)
dc950861 1090 scsicmd->scsi_done(scsicmd);
dc950861
KC
1091}
1092
1093static inline void
1094complete_vdiskmgmt_command(struct uiscmdrsp *cmdrsp)
1095{
1096 /* copy the result of the taskmgmt and */
1097 /* wake up the error handler that is waiting for this */
396beed6
KD
1098 *(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
1099 wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify);
dc950861
KC
1100}
1101
1102static inline void
1103complete_taskmgmt_command(struct uiscmdrsp *cmdrsp)
1104{
1105 /* copy the result of the taskmgmt and */
1106 /* wake up the error handler that is waiting for this */
396beed6 1107 *(int *)cmdrsp->scsitaskmgmt.notifyresult =
dc950861 1108 cmdrsp->scsitaskmgmt.result;
396beed6 1109 wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify);
dc950861
KC
1110}
1111
1112static void
1113drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
836600fa 1114 struct uiscmdrsp *cmdrsp)
dc950861
KC
1115{
1116 unsigned long flags;
1117 int qrslt = 0;
1118 struct scsi_cmnd *scsicmd;
1119 struct Scsi_Host *shost = virthbainfo->scsihost;
1120
1121 while (1) {
1122 spin_lock_irqsave(&virthbainfo->chinfo.insertlock, flags);
9f16930e 1123 if (!spar_channel_client_acquire_os(dc->queueinfo->chan,
836600fa 1124 "vhba")) {
dc950861
KC
1125 spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock,
1126 flags);
1127 virthbainfo->acquire_failed_cnt++;
1128 break;
1129 }
1130 qrslt = uisqueue_get_cmdrsp(dc->queueinfo, cmdrsp,
1131 IOCHAN_FROM_IOPART);
08598918 1132 spar_channel_client_release_os(dc->queueinfo->chan, "vhba");
dc950861
KC
1133 spin_unlock_irqrestore(&virthbainfo->chinfo.insertlock, flags);
1134 if (qrslt == 0)
1135 break;
1136 if (cmdrsp->cmdtype == CMD_SCSI_TYPE) {
1137 /* scsicmd location is returned by the
1138 * deletion
1139 */
1140 scsicmd = del_scsipending_entry(virthbainfo,
a57fc10e
KD
1141 (uintptr_t)
1142 cmdrsp->scsi.scsicmd);
dc950861
KC
1143 if (!scsicmd)
1144 break;
1145 /* complete the orig cmd */
1146 complete_scsi_command(cmdrsp, scsicmd);
1147 } else if (cmdrsp->cmdtype == CMD_SCSITASKMGMT_TYPE) {
1148 if (!del_scsipending_entry(virthbainfo,
396beed6 1149 (uintptr_t)cmdrsp->scsitaskmgmt.scsicmd))
dc950861
KC
1150 break;
1151 complete_taskmgmt_command(cmdrsp);
1152 } else if (cmdrsp->cmdtype == CMD_NOTIFYGUEST_TYPE) {
1153 /* The vHba pointer has no meaning in
1154 * a Client/Guest Partition. Let's be
1155 * safe and set it to NULL now. Do
1156 * not use it here! */
be3c3669 1157 cmdrsp->disknotify.v_hba = NULL;
dc950861
KC
1158 process_disk_notify(shost, cmdrsp);
1159 } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) {
1160 if (!del_scsipending_entry(virthbainfo,
a57fc10e
KD
1161 (uintptr_t)
1162 cmdrsp->vdiskmgmt.scsicmd))
dc950861
KC
1163 break;
1164 complete_vdiskmgmt_command(cmdrsp);
0aca7844 1165 }
dc950861
KC
1166 /* cmdrsp is now available for reuse */
1167 }
1168}
1169
dc950861
KC
1170/* main function for the thread that waits for scsi commands to arrive
1171 * in a specified queue
1172 */
1173static int
1174process_incoming_rsps(void *v)
1175{
1176 struct virthba_info *virthbainfo = v;
1177 struct chaninfo *dc = &virthbainfo->chinfo;
1178 struct uiscmdrsp *cmdrsp = NULL;
1179 const int SZ = sizeof(struct uiscmdrsp);
5fc0229a 1180 u64 mask;
dc950861
KC
1181 unsigned long long rc1;
1182
1183 UIS_DAEMONIZE("vhba_incoming");
1184 /* alloc once and reuse */
1185 cmdrsp = kmalloc(SZ, GFP_ATOMIC);
5af3b098 1186 if (!cmdrsp) {
dc950861
KC
1187 complete_and_exit(&dc->threadinfo.has_stopped, 0);
1188 return 0;
1189 }
1190 mask = ULTRA_CHANNEL_ENABLE_INTS;
1191 while (1) {
010c9f8e
DN
1192 if (kthread_should_stop())
1193 break;
dc950861
KC
1194 wait_event_interruptible_timeout(virthbainfo->rsp_queue,
1195 (atomic_read(&virthbainfo->interrupt_rcvd) == 1),
836600fa 1196 usecs_to_jiffies(rsltq_wait_usecs));
dc950861
KC
1197 atomic_set(&virthbainfo->interrupt_rcvd, 0);
1198 /* drain queue */
1199 drain_queue(virthbainfo, dc, cmdrsp);
17f5e491 1200 rc1 = uisqueue_interlocked_or(virthbainfo->flags_addr, mask);
dc950861
KC
1201 }
1202
1203 kfree(cmdrsp);
1204
dc950861
KC
1205 complete_and_exit(&dc->threadinfo.has_stopped, 0);
1206}
1207
d9c5607e
EA
1208/*****************************************************/
1209/* Debugfs filesystem functions */
1210/*****************************************************/
1211
1212static ssize_t info_debugfs_read(struct file *file,
836600fa 1213 char __user *buf, size_t len, loff_t *offset)
d9c5607e
EA
1214{
1215 ssize_t bytes_read = 0;
1216 int str_pos = 0;
5fc0229a 1217 u64 phys_flags_addr;
d9c5607e
EA
1218 int i;
1219 struct virthba_info *virthbainfo;
1220 char *vbuf;
1221
1222 if (len > MAX_BUF)
1223 len = MAX_BUF;
1224 vbuf = kzalloc(len, GFP_KERNEL);
1225 if (!vbuf)
1226 return -ENOMEM;
1227
1228 for (i = 0; i < VIRTHBASOPENMAX; i++) {
5af3b098 1229 if (!virthbas_open[i].virthbainfo)
d9c5607e
EA
1230 continue;
1231
366cf71a 1232 virthbainfo = virthbas_open[i].virthbainfo;
d9c5607e
EA
1233
1234 str_pos += scnprintf(vbuf + str_pos,
366cf71a
KD
1235 len - str_pos, "max_buff_len:%u\n",
1236 max_buff_len);
d9c5607e
EA
1237
1238 str_pos += scnprintf(vbuf + str_pos, len - str_pos,
1239 "\nvirthba result queue poll wait:%d usecs.\n",
1240 rsltq_wait_usecs);
1241 str_pos += scnprintf(vbuf + str_pos, len - str_pos,
1242 "\ninterrupts_rcvd = %llu, interrupts_disabled = %llu\n",
1243 virthbainfo->interrupts_rcvd,
1244 virthbainfo->interrupts_disabled);
1245 str_pos += scnprintf(vbuf + str_pos,
1246 len - str_pos, "\ninterrupts_notme = %llu,\n",
1247 virthbainfo->interrupts_notme);
1248 phys_flags_addr = virt_to_phys((__force void *)
1249 virthbainfo->flags_addr);
1250 str_pos += scnprintf(vbuf + str_pos, len - str_pos,
1251 "flags_addr = %p, phys_flags_addr=0x%016llx, FeatureFlags=%llu\n",
1252 virthbainfo->flags_addr, phys_flags_addr,
1253 (__le64)readq(virthbainfo->flags_addr));
1254 str_pos += scnprintf(vbuf + str_pos,
1255 len - str_pos, "acquire_failed_cnt:%llu\n",
1256 virthbainfo->acquire_failed_cnt);
1257 str_pos += scnprintf(vbuf + str_pos, len - str_pos, "\n");
1258 }
1259
1260 bytes_read = simple_read_from_buffer(buf, len, offset, vbuf, str_pos);
1261 kfree(vbuf);
1262 return bytes_read;
1263}
1264
836600fa
KD
1265static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
1266 size_t count, loff_t *ppos)
79014eb1
EA
1267{
1268 char buf[4];
1269 int i, new_value;
1270 struct virthba_info *virthbainfo;
1271
05f35980 1272 u64 __iomem *features_addr;
5fc0229a 1273 u64 mask;
79014eb1
EA
1274
1275 if (count >= ARRAY_SIZE(buf))
1276 return -EINVAL;
1277
1278 buf[count] = '\0';
0aca7844 1279 if (copy_from_user(buf, buffer, count))
79014eb1 1280 return -EFAULT;
79014eb1 1281
29d58624 1282 i = kstrtoint(buf, 10, &new_value);
79014eb1 1283
0aca7844 1284 if (i != 0)
79014eb1 1285 return -EFAULT;
79014eb1 1286
cfe4571f 1287 /* set all counts to new_value usually 0 */
79014eb1 1288 for (i = 0; i < VIRTHBASOPENMAX; i++) {
5af3b098 1289 if (virthbas_open[i].virthbainfo) {
366cf71a 1290 virthbainfo = virthbas_open[i].virthbainfo;
05f35980 1291 features_addr =
a8a31f61 1292 &virthbainfo->chinfo.queueinfo->chan->features;
79014eb1
EA
1293 if (new_value == 1) {
1294 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
1295 ULTRA_IO_DRIVER_DISABLES_INTS);
05f35980 1296 uisqueue_interlocked_and(features_addr, mask);
79014eb1 1297 mask = ULTRA_IO_DRIVER_ENABLES_INTS;
05f35980 1298 uisqueue_interlocked_or(features_addr, mask);
79014eb1
EA
1299 rsltq_wait_usecs = 4000000;
1300 } else {
1301 mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS |
1302 ULTRA_IO_DRIVER_DISABLES_INTS);
05f35980 1303 uisqueue_interlocked_and(features_addr, mask);
79014eb1 1304 mask = ULTRA_IO_CHANNEL_IS_POLLING;
05f35980 1305 uisqueue_interlocked_or(features_addr, mask);
79014eb1
EA
1306 rsltq_wait_usecs = 4000;
1307 }
1308 }
1309 }
1310 return count;
1311}
1312
dc950861
KC
1313/* As per VirtpciFunc returns 1 for success and 0 for failure */
1314static int
1315virthba_serverup(struct virtpci_dev *virtpcidev)
1316{
1317 struct virthba_info *virthbainfo =
396beed6 1318 (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
dc950861
KC
1319 scsihost)->hostdata;
1320
4de57acb 1321 if (!virthbainfo->serverdown)
dc950861 1322 return 1;
4de57acb 1323
0aca7844 1324 if (virthbainfo->serverchangingstate)
dc950861 1325 return 0;
dc950861
KC
1326
1327 virthbainfo->serverchangingstate = true;
1328 /* Must transition channel to ATTACHED state BEFORE we
1329 * can start using the device again
1330 */
ff97a3fd
BR
1331 SPAR_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan,
1332 dev_name(&virtpcidev->generic_dev),
1333 CHANNELCLI_ATTACHED, NULL);
dc950861
KC
1334
1335 /* Start Processing the IOVM Response Queue Again */
1336 if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
1337 process_incoming_rsps,
1338 virthbainfo, "vhba_incoming")) {
dc950861
KC
1339 return 0;
1340 }
1341 virthbainfo->serverdown = false;
1342 virthbainfo->serverchangingstate = false;
1343
1344 return 1;
1345}
1346
1347static void
1348virthba_serverdown_complete(struct work_struct *work)
1349{
1350 struct virthba_info *virthbainfo;
1351 struct virtpci_dev *virtpcidev;
1352 int i;
1353 struct scsipending *pendingdel = NULL;
1354 struct scsi_cmnd *scsicmd = NULL;
1355 struct uiscmdrsp *cmdrsp;
1356 unsigned long flags;
1357
1358 virthbainfo = container_of(work, struct virthba_info,
1359 serverdown_completion);
1360
1361 /* Stop Using the IOVM Response Queue (queue should be drained
1362 * by the end)
1363 */
1364 uisthread_stop(&virthbainfo->chinfo.threadinfo);
1365
1366 /* Fail Commands that weren't completed */
1367 spin_lock_irqsave(&virthbainfo->privlock, flags);
1368 for (i = 0; i < MAX_PENDING_REQUESTS; i++) {
1cc598c7 1369 pendingdel = &virthbainfo->pending[i];
dc950861
KC
1370 switch (pendingdel->cmdtype) {
1371 case CMD_SCSI_TYPE:
396beed6 1372 scsicmd = (struct scsi_cmnd *)pendingdel->sent;
a0648724 1373 scsicmd->result = DID_RESET << 16;
dc950861
KC
1374 if (scsicmd->scsi_done)
1375 scsicmd->scsi_done(scsicmd);
1376 break;
1377 case CMD_SCSITASKMGMT_TYPE:
396beed6 1378 cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
dc950861
KC
1379 wake_up_all((wait_queue_head_t *)
1380 cmdrsp->scsitaskmgmt.notify);
4de57acb
BR
1381 *(int *)cmdrsp->scsitaskmgmt.notifyresult =
1382 TASK_MGMT_FAILED;
dc950861
KC
1383 break;
1384 case CMD_VDISKMGMT_TYPE:
396beed6
KD
1385 cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
1386 *(int *)cmdrsp->vdiskmgmt.notifyresult =
dc950861
KC
1387 VDISK_MGMT_FAILED;
1388 wake_up_all((wait_queue_head_t *)
1389 cmdrsp->vdiskmgmt.notify);
1390 break;
1391 default:
0aca7844 1392 break;
dc950861
KC
1393 }
1394 pendingdel->cmdtype = 0;
1395 pendingdel->sent = NULL;
1396 }
1397 spin_unlock_irqrestore(&virthbainfo->privlock, flags);
1398
1399 virtpcidev = virthbainfo->virtpcidev;
1400
dc950861
KC
1401 virthbainfo->serverdown = true;
1402 virthbainfo->serverchangingstate = false;
1403 /* Return the ServerDown response to Command */
55f714cd
BR
1404 visorchipset_device_pause_response(virtpcidev->bus_no,
1405 virtpcidev->device_no, 0);
dc950861
KC
1406}
1407
1408/* As per VirtpciFunc returns 1 for success and 0 for failure */
1409static int
1410virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
1411{
20078e48
KD
1412 int stat = 1;
1413
dc950861 1414 struct virthba_info *virthbainfo =
396beed6 1415 (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
dc950861
KC
1416 scsihost)->hostdata;
1417
dc950861
KC
1418 if (!virthbainfo->serverdown && !virthbainfo->serverchangingstate) {
1419 virthbainfo->serverchangingstate = true;
1420 queue_work(virthba_serverdown_workqueue,
1421 &virthbainfo->serverdown_completion);
1422 } else if (virthbainfo->serverchangingstate) {
20078e48 1423 stat = 0;
20078e48 1424 }
dc950861 1425
20078e48 1426 return stat;
dc950861
KC
1427}
1428
1429/*****************************************************/
1430/* Module Init & Exit functions */
1431/*****************************************************/
1432
1433static int __init
1434virthba_parse_line(char *str)
1435{
dc950861
KC
1436 return 1;
1437}
1438
1439static void __init
1440virthba_parse_options(char *line)
1441{
1442 char *next = line;
1443
1444 POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
5af3b098 1445 if (!line || !*line)
dc950861 1446 return;
5af3b098 1447 while ((line = next)) {
dc950861 1448 next = strchr(line, ' ');
5af3b098 1449 if (next)
dc950861 1450 *next++ = 0;
4de57acb 1451 virthba_parse_line(line);
dc950861
KC
1452 }
1453
1454 POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
1455}
1456
1457static int __init
1458virthba_mod_init(void)
1459{
1460 int error;
1461 int i;
1462
fcd0157e
KC
1463 if (!unisys_spar_platform)
1464 return -ENODEV;
1465
dc950861
KC
1466 POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
1467 virthba_parse_options(virthba_options);
1468
1469 error = virtpci_register_driver(&virthba_driver);
1470 if (error < 0) {
dc950861
KC
1471 POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
1472 POSTCODE_SEVERITY_ERR);
1473 } else {
d9c5607e
EA
1474 /* create the debugfs directories and entries */
1475 virthba_debugfs_dir = debugfs_create_dir("virthba", NULL);
1476 debugfs_create_file("info", S_IRUSR, virthba_debugfs_dir,
836600fa 1477 NULL, &debugfs_info_fops);
5d150191 1478 debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
836600fa 1479 virthba_debugfs_dir, &rsltq_wait_usecs);
79014eb1 1480 debugfs_create_file("enable_ints", S_IWUSR,
836600fa
KD
1481 virthba_debugfs_dir, NULL,
1482 &debugfs_enable_ints_fops);
1483 /* Initialize dar_work_queue */
b6e0a708 1484 INIT_WORK(&dar_work_queue, do_disk_add_remove);
83afa349 1485 spin_lock_init(&dar_work_queue_lock);
dc950861
KC
1486
1487 /* clear out array */
1488 for (i = 0; i < VIRTHBASOPENMAX; i++)
366cf71a 1489 virthbas_open[i].virthbainfo = NULL;
dc950861
KC
1490 /* Initialize the serverdown workqueue */
1491 virthba_serverdown_workqueue =
1492 create_singlethread_workqueue("virthba_serverdown");
5af3b098 1493 if (!virthba_serverdown_workqueue) {
dc950861
KC
1494 POSTCODE_LINUX_2(VHBA_CREATE_FAILURE_PC,
1495 POSTCODE_SEVERITY_ERR);
1496 error = -1;
1497 }
1498 }
1499
1500 POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
dc950861
KC
1501 return error;
1502}
1503
1504static ssize_t
1505virthba_acquire_lun(struct device *cdev, struct device_attribute *attr,
1506 const char *buf, size_t count)
1507{
1508 struct uisscsi_dest vdest;
1509 struct Scsi_Host *shost = class_to_shost(cdev);
1510 int i;
1511
1512 i = sscanf(buf, "%d-%d-%d", &vdest.channel, &vdest.id, &vdest.lun);
1513 if (i != 3)
1514 return i;
1515
1516 return forward_vdiskmgmt_command(VDISK_MGMT_ACQUIRE, shost, &vdest);
1517}
1518
1519static ssize_t
1520virthba_release_lun(struct device *cdev, struct device_attribute *attr,
1521 const char *buf, size_t count)
1522{
1523 struct uisscsi_dest vdest;
1524 struct Scsi_Host *shost = class_to_shost(cdev);
1525 int i;
1526
1527 i = sscanf(buf, "%d-%d-%d", &vdest.channel, &vdest.id, &vdest.lun);
1528 if (i != 3)
1529 return i;
1530
1531 return forward_vdiskmgmt_command(VDISK_MGMT_RELEASE, shost, &vdest);
1532}
1533
1534#define CLASS_DEVICE_ATTR(_name, _mode, _show, _store) \
1535 struct device_attribute class_device_attr_##_name = \
1536 __ATTR(_name, _mode, _show, _store)
1537
1538static CLASS_DEVICE_ATTR(acquire_lun, S_IWUSR, NULL, virthba_acquire_lun);
1539static CLASS_DEVICE_ATTR(release_lun, S_IWUSR, NULL, virthba_release_lun);
1540
1541static DEVICE_ATTRIBUTE *virthba_shost_attrs[] = {
1542 &class_device_attr_acquire_lun,
1543 &class_device_attr_release_lun,
1544 NULL
1545};
1546
1547static void __exit
1548virthba_mod_exit(void)
1549{
dc950861
KC
1550 virtpci_unregister_driver(&virthba_driver);
1551 /* unregister is going to call virthba_remove */
1552 /* destroy serverdown completion workqueue */
1553 if (virthba_serverdown_workqueue) {
1554 destroy_workqueue(virthba_serverdown_workqueue);
1555 virthba_serverdown_workqueue = NULL;
1556 }
1557
d9c5607e 1558 debugfs_remove_recursive(virthba_debugfs_dir);
dc950861
KC
1559}
1560
1561/* specify function to be run at module insertion time */
1562module_init(virthba_mod_init);
1563
1564/* specify function to be run when module is removed */
1565module_exit(virthba_mod_exit);
1566
1567MODULE_LICENSE("GPL");
1568MODULE_AUTHOR("Usha Srinivasan");
1569MODULE_ALIAS("uisvirthba");
1570 /* this is extracted during depmod and kept in modules.dep */
1571/* module parameter */
1572module_param(virthba_options, charp, S_IRUGO);