Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / staging / unisys / virthba / virthba.c
1 /* virthba.c
2  *
3  * Copyright (C) 2010 - 2013 UNISYS CORPORATION
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
29 #include <linux/kernel.h>
30 #ifdef CONFIG_MODVERSIONS
31 #include <config/modversions.h>
32 #endif
33
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>
50 #include <linux/debugfs.h>
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
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
72 /*****************************************************/
73 /* Forward declarations                              */
74 /*****************************************************/
75 static int virthba_probe(struct virtpci_dev *dev,
76                          const struct pci_device_id *id);
77 static void virthba_remove(struct virtpci_dev *dev);
78 static int virthba_abort_handler(struct scsi_cmnd *scsicmd);
79 static int virthba_bus_reset_handler(struct scsi_cmnd *scsicmd);
80 static int virthba_device_reset_handler(struct scsi_cmnd *scsicmd);
81 static int virthba_host_reset_handler(struct scsi_cmnd *scsicmd);
82 static const char *virthba_get_info(struct Scsi_Host *shp);
83 static int virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
84 static int virthba_queue_command_lck(struct scsi_cmnd *scsicmd,
85                                      void (*virthba_cmnd_done)
86                                            (struct scsi_cmnd *));
87
88 static const struct x86_cpu_id unisys_spar_ids[] = {
89         { X86_VENDOR_INTEL, 6, 62, X86_FEATURE_ANY },
90         {}
91 };
92
93 /* Autoload */
94 MODULE_DEVICE_TABLE(x86cpu, unisys_spar_ids);
95
96 #ifdef DEF_SCSI_QCMD
97 static DEF_SCSI_QCMD(virthba_queue_command)
98 #else
99 #define virthba_queue_command virthba_queue_command_lck
100 #endif
101
102 static int virthba_slave_alloc(struct scsi_device *scsidev);
103 static int virthba_slave_configure(struct scsi_device *scsidev);
104 static void virthba_slave_destroy(struct scsi_device *scsidev);
105 static int process_incoming_rsps(void *);
106 static int virthba_serverup(struct virtpci_dev *virtpcidev);
107 static int virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state);
108 static void do_disk_add_remove(struct work_struct *work);
109 static void virthba_serverdown_complete(struct work_struct *work);
110 static ssize_t info_debugfs_read(struct file *file, char __user *buf,
111                                  size_t len, loff_t *offset);
112 static ssize_t enable_ints_write(struct file *file,
113                                  const char __user *buffer, size_t count,
114                                  loff_t *ppos);
115
116 /*****************************************************/
117 /* Globals                                           */
118 /*****************************************************/
119
120 static int rsltq_wait_usecs = 4000;     /* Default 4ms */
121 static unsigned int max_buff_len;
122
123 /* Module options */
124 static char *virthba_options = "NONE";
125
126 static 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 */
132 MODULE_DEVICE_TABLE(pci, virthba_id_table);
133
134 static struct workqueue_struct *virthba_serverdown_workqueue;
135
136 static struct virtpci_driver virthba_driver = {
137         .name = "uisvirthba",
138         .version = VERSION,
139         .vertag = NULL,
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
151 struct 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
160 struct virtdisk_info {
161         u32 valid;
162         u32 channel, id, lun;   /* Disk Path */
163         atomic_t ios_threshold;
164         atomic_t error_count;
165         struct virtdisk_info *next;
166 };
167
168 /* Each Scsi_Host has a host_data area that contains this struct. */
169 struct virthba_info {
170         struct Scsi_Host *scsihost;
171         struct virtpci_dev *virtpcidev;
172         struct list_head dev_info_list;
173         struct chaninfo chinfo;
174         struct irq_info intr;           /* use recvInterrupt info to receive
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;
190         u64 __iomem *flags_addr;
191         atomic_t interrupt_rcvd;
192         wait_queue_head_t rsp_queue;
193         struct virtdisk_info head;
194 };
195
196 /* Work Data for dar_work_queue */
197 struct diskaddremove {
198         u8 add;                 /* 0-remove, 1-add */
199         struct Scsi_Host *shost; /* Scsi Host for this virthba instance */
200         u32 channel, id, lun;   /* Disk Path */
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
207 static DEVICE_ATTRIBUTE *virthba_shost_attrs[];
208 static struct scsi_host_template virthba_driver_template = {
209         .name = "Unisys Virtual HBA",
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
229 struct virthba_devices_open {
230         struct virthba_info *virthbainfo;
231 };
232
233 static const struct file_operations debugfs_info_fops = {
234         .read = info_debugfs_read,
235 };
236
237 static const struct file_operations debugfs_enable_ints_fops = {
238         .write = enable_ints_write,
239 };
240
241 /*****************************************************/
242 /* Structs                                           */
243 /*****************************************************/
244
245 #define VIRTHBASOPENMAX 1
246 /* array of open devices maintained by open() and close(); */
247 static struct virthba_devices_open virthbas_open[VIRTHBASOPENMAX];
248 static struct dentry *virthba_debugfs_dir;
249
250 /*****************************************************/
251 /* Local Functions                                   */
252 /*****************************************************/
253 static int
254 add_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;
261         while (vhbainfo->pending[insert_location].sent) {
262                 insert_location = (insert_location + 1) % MAX_PENDING_REQUESTS;
263                 if (insert_location == (int)vhbainfo->nextinsert) {
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
277 static unsigned int
278 add_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) {
284                 set_current_state(TASK_INTERRUPTIBLE);
285                 schedule_timeout(msecs_to_jiffies(10));
286                 insert_location = add_scsipending_entry(vhbainfo, cmdtype, new);
287         }
288
289         return (unsigned int)insert_location;
290 }
291
292 static void *
293 del_scsipending_entry(struct virthba_info *vhbainfo, uintptr_t del)
294 {
295         unsigned long flags;
296         void *sent = NULL;
297
298         if (del < MAX_PENDING_REQUESTS) {
299                 spin_lock_irqsave(&vhbainfo->privlock, flags);
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
310 /* dar_work_queue (Disk Add/Remove) */
311 static struct work_struct dar_work_queue;
312 static struct diskaddremove *dar_work_queue_head;
313 static spinlock_t dar_work_queue_lock;
314 static unsigned short dar_work_queue_sched;
315 #define QUEUE_DISKADDREMOVE(dar) { \
316         spin_lock_irqsave(&dar_work_queue_lock, flags); \
317         if (!dar_work_queue_head) { \
318                 dar_work_queue_head = dar; \
319                 dar->next = NULL; \
320         } \
321         else { \
322                 dar->next = dar_work_queue_head; \
323                 dar_work_queue_head = dar; \
324         } \
325         if (!dar_work_queue_sched) { \
326                 schedule_work(&dar_work_queue); \
327                 dar_work_queue_sched = 1; \
328         } \
329         spin_unlock_irqrestore(&dar_work_queue_lock, flags); \
330 }
331
332 static inline void
333 send_disk_add_remove(struct diskaddremove *dar)
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);
346         }
347         kfree(dar);
348 }
349
350 /*****************************************************/
351 /* dar_work_queue Handler Thread                     */
352 /*****************************************************/
353 static void
354 do_disk_add_remove(struct work_struct *work)
355 {
356         struct diskaddremove *dar;
357         struct diskaddremove *tmphead;
358         int i = 0;
359         unsigned long flags;
360
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);
366         while (tmphead) {
367                 dar = tmphead;
368                 tmphead = dar->next;
369                 send_disk_add_remove(dar);
370                 i++;
371         }
372 }
373
374 /*****************************************************/
375 /* Routine to add entry to dar_work_queue            */
376 /*****************************************************/
377 static void
378 process_disk_notify(struct Scsi_Host *shost, struct uiscmdrsp *cmdrsp)
379 {
380         struct diskaddremove *dar;
381         unsigned long flags;
382
383         dar = kzalloc(sizeof(*dar), GFP_ATOMIC);
384         if (dar) {
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);
391         }
392 }
393
394 /*****************************************************/
395 /* Probe Remove Functions                            */
396 /*****************************************************/
397 static irqreturn_t
398 virthba_isr(int irq, void *dev_id)
399 {
400         struct virthba_info *virthbainfo = (struct virthba_info *)dev_id;
401         struct channel_header __iomem *channel_header;
402         struct signal_queue_header __iomem *pqhdr;
403         u64 mask;
404         unsigned long long rc1;
405
406         if (!virthbainfo)
407                 return IRQ_NONE;
408         virthbainfo->interrupts_rcvd++;
409         channel_header = virthbainfo->chinfo.queueinfo->chan;
410         if (((readq(&channel_header->features)
411               & ULTRA_IO_IOVM_IS_OK_WITH_DRIVER_DISABLING_INTS) != 0) &&
412              ((readq(&channel_header->features) &
413                  ULTRA_IO_DRIVER_DISABLES_INTS) !=
414                 0)) {
415                 virthbainfo->interrupts_disabled++;
416                 mask = ~ULTRA_CHANNEL_ENABLE_INTS;
417                 rc1 = uisqueue_interlocked_and(virthbainfo->flags_addr, mask);
418         }
419         if (spar_signalqueue_empty(channel_header, IOCHAN_FROM_IOPART)) {
420                 virthbainfo->interrupts_notme++;
421                 return IRQ_NONE;
422         }
423         pqhdr = (struct signal_queue_header __iomem *)
424                 ((char __iomem *)channel_header +
425                  readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
426         writeq(readq(&pqhdr->num_irq_received) + 1,
427                &pqhdr->num_irq_received);
428         atomic_set(&virthbainfo->interrupt_rcvd, 1);
429         wake_up_interruptible(&virthbainfo->rsp_queue);
430         return IRQ_HANDLED;
431 }
432
433 static int
434 virthba_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;
441         irq_handler_t handler = virthba_isr;
442         struct channel_header __iomem *channel_header;
443         struct signal_queue_header __iomem *pqhdr;
444         u64 mask;
445
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
451          * initialization.  The host is not published to the scsi
452          * midlayer until scsi_add_host is called.
453          */
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));
461         if (!scsihost)
462                 return -ENODEV;
463
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          */
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;
475         scsihost->max_sectors =
476             (unsigned short)(virtpcidev->scsi.max.max_io_size >> 9);
477         scsihost->sg_tablesize =
478             (unsigned short)(virtpcidev->scsi.max.max_io_size / PAGE_SIZE);
479         if (scsihost->sg_tablesize > MAX_PHYS_INFO)
480                 scsihost->sg_tablesize = MAX_PHYS_INFO;
481
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) {
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
499         virthbainfo = (struct virthba_info *)scsihost->hostdata;
500         memset(virthbainfo, 0, sizeof(struct virthba_info));
501         for (i = 0; i < VIRTHBASOPENMAX; i++) {
502                 if (!virthbas_open[i].virthbainfo) {
503                         virthbas_open[i].virthbainfo = virthbainfo;
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
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
529         writeq(readq(&virthbainfo->chinfo.queueinfo->chan->features) |
530                ULTRA_IO_CHANNEL_IS_POLLING,
531                &virthbainfo->chinfo.queueinfo->chan->features);
532         /* start thread that will receive scsicmnd responses */
533
534         channel_header = virthbainfo->chinfo.queueinfo->chan;
535         pqhdr = (struct signal_queue_header __iomem *)
536                 ((char __iomem *)channel_header +
537                  readq(&channel_header->ch_space_offset)) + IOCHAN_FROM_IOPART;
538         virthbainfo->flags_addr = &pqhdr->features;
539
540         if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
541                              process_incoming_rsps,
542                              virthbainfo, "vhba_incoming")) {
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         }
550         virthbainfo->interrupt_vector =
551             virthbainfo->intr.recv_irq_handle & INTERRUPT_VECTOR_MASK;
552         rsp = request_irq(virthbainfo->interrupt_vector, handler, IRQF_SHARED,
553                           scsihost->hostt->name, virthbainfo);
554         if (rsp != 0) {
555                 virthbainfo->interrupt_vector = -1;
556                 POSTCODE_LINUX_2(VHBA_PROBE_FAILURE_PC, POSTCODE_SEVERITY_ERR);
557         } else {
558                 u64 __iomem *features_addr =
559                     &virthbainfo->chinfo.queueinfo->chan->features;
560                 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
561                          ULTRA_IO_DRIVER_DISABLES_INTS);
562                 uisqueue_interlocked_and(features_addr, mask);
563                 mask = ULTRA_IO_DRIVER_ENABLES_INTS;
564                 uisqueue_interlocked_or(features_addr, mask);
565                 rsltq_wait_usecs = 4000000;
566         }
567
568         scsi_scan_host(scsihost);
569
570         POSTCODE_LINUX_2(VHBA_PROBE_EXIT_PC, POSTCODE_SEVERITY_INFO);
571         return 0;
572 }
573
574 static void
575 virthba_remove(struct virtpci_dev *virtpcidev)
576 {
577         struct virthba_info *virthbainfo;
578         struct Scsi_Host *scsihost =
579             (struct Scsi_Host *)virtpcidev->scsi.scsihost;
580
581         virthbainfo = (struct virthba_info *)scsihost->hostdata;
582         if (virthbainfo->interrupt_vector != -1)
583                 free_irq(virthbainfo->interrupt_vector, virthbainfo);
584
585         scsi_remove_host(scsihost);
586
587         uisthread_stop(&virthbainfo->chinfo.threadinfo);
588
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);
593 }
594
595 static int
596 forward_vdiskmgmt_command(enum vdisk_mgmt_types vdiskcmdtype,
597                           struct Scsi_Host *scsihost,
598                           struct uisscsi_dest *vdest)
599 {
600         struct uiscmdrsp *cmdrsp;
601         struct virthba_info *virthbainfo =
602             (struct virthba_info *)scsihost->hostdata;
603         int notifyresult = 0xffff;
604         wait_queue_head_t notifyevent;
605
606         if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
607                 return FAILED;
608
609         cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
610         if (!cmdrsp)
611                 return FAILED;  /* reject */
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          */
622         cmdrsp->vdiskmgmt.notify = (void *)&notifyevent;
623         cmdrsp->vdiskmgmt.notifyresult = (void *)&notifyresult;
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 =
631             (void *)(uintptr_t)
632                 add_scsipending_entry_with_wait(virthbainfo, CMD_VDISKMGMT_TYPE,
633                                                 (void *)cmdrsp);
634
635         uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
636                                              cmdrsp, IOCHAN_TO_IOPART,
637                                              &virthbainfo->chinfo.insertlock,
638                                              DONT_ISSUE_INTERRUPT, (u64)NULL,
639                                              OK_TO_WAIT, "vhba");
640         wait_event(notifyevent, notifyresult != 0xffff);
641         kfree(cmdrsp);
642         return SUCCESS;
643 }
644
645 /*****************************************************/
646 /* Scsi Host support functions                       */
647 /*****************************************************/
648
649 static int
650 forward_taskmgmt_command(enum task_mgmt_types tasktype,
651                          struct scsi_device *scsidev)
652 {
653         struct uiscmdrsp *cmdrsp;
654         struct virthba_info *virthbainfo =
655             (struct virthba_info *)scsidev->host->hostdata;
656         int notifyresult = 0xffff;
657         wait_queue_head_t notifyevent;
658
659         if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
660                 return FAILED;
661
662         cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
663         if (!cmdrsp)
664                 return FAILED;  /* reject */
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 */
673         cmdrsp->scsitaskmgmt.notify = (void *)&notifyevent;
674         cmdrsp->scsitaskmgmt.notifyresult = (void *)&notifyresult;
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 =
682             (void *)(uintptr_t)
683                 add_scsipending_entry_with_wait(virthbainfo,
684                                                 CMD_SCSITASKMGMT_TYPE,
685                                                 (void *)cmdrsp);
686
687         uisqueue_put_cmdrsp_with_lock_client(virthbainfo->chinfo.queueinfo,
688                                              cmdrsp, IOCHAN_TO_IOPART,
689                                              &virthbainfo->chinfo.insertlock,
690                                              DONT_ISSUE_INTERRUPT, (u64)NULL,
691                                              OK_TO_WAIT, "vhba");
692         wait_event(notifyevent, notifyresult != 0xffff);
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  */
700 static int
701 virthba_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;
708         for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
709              vdisk->next; vdisk = vdisk->next) {
710                 if ((scsidev->channel == vdisk->channel) &&
711                     (scsidev->id == vdisk->id) &&
712                     (scsidev->lun == vdisk->lun)) {
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
726 static int
727 virthba_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;
734         for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
735              vdisk->next; vdisk = vdisk->next) {
736                 if ((scsidev->channel == vdisk->channel) &&
737                     (scsidev->id == vdisk->id) &&
738                     (scsidev->lun == vdisk->lun)) {
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
752 static int
753 virthba_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;
760         for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
761              vdisk->next; vdisk = vdisk->next) {
762                 if ((scsidev->channel == vdisk->channel) &&
763                     (scsidev->id == vdisk->id) &&
764                     (scsidev->lun == vdisk->lun)) {
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
778 static int
779 virthba_host_reset_handler(struct scsi_cmnd *scsicmd)
780 {
781         /* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
782         return SUCCESS;
783 }
784
785 static char virthba_get_info_str[256];
786
787 static const char *
788 virthba_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
795 static int
796 virthba_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
797 {
798         return -EINVAL;
799 }
800
801 /* This returns SCSI_MLQUEUE_DEVICE_BUSY if the signal queue to IOpart
802  * is full.
803  */
804 static int
805 virthba_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 =
816             (struct virthba_info *)scsihost->hostdata;
817         struct scatterlist *sg = NULL;
818         struct scatterlist *sgl = NULL;
819         int sg_failed = 0;
820
821         if (virthbainfo->serverdown || virthbainfo->serverchangingstate)
822                 return SCSI_MLQUEUE_DEVICE_BUSY;
823         cmdrsp = kzalloc(SIZEOF_CMDRSP, GFP_ATOMIC);
824         if (!cmdrsp)
825                 return 1;       /* reject the command */
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 =
836             add_scsipending_entry(virthbainfo, CMD_SCSI_TYPE, (void *)scsicmd);
837         if (insert_location != -1) {
838                 cmdrsp->scsi.scsicmd = (void *)(uintptr_t)insert_location;
839         } else {
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. */
856         if (cmdrsp->scsi.bufflen > max_buff_len)
857                 max_buff_len = cmdrsp->scsi.bufflen;
858
859         if (scsi_sg_count(scsicmd) > MAX_PHYS_INFO) {
860                 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
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) {
872                         BUG_ON(scsi_sg_count(scsicmd) == 0);
873                 }
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) {
879                         cmdrsp->scsi.gpi_list[i].address = sg_phys(sg);
880                         cmdrsp->scsi.gpi_list[i].length = sg->length;
881                 }
882
883                 if (sg_failed) {
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,
899                                                  (u64)NULL, DONT_WAIT, "vhba");
900         if (i == 0) {
901                 /* queue must be full - and we said don't wait - return busy */
902                 kfree(cmdrsp);
903                 del_scsipending_entry(virthbainfo, (uintptr_t)insert_location);
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
914 static int
915 virthba_slave_alloc(struct scsi_device *scsidev)
916 {
917         /* this called by the midlayer before scan for new devices -
918          * LLD can alloc any struct & do init if needed.
919          */
920         struct virtdisk_info *vdisk;
921         struct virtdisk_info *tmpvdisk;
922         struct virthba_info *virthbainfo;
923         struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
924
925         virthbainfo = (struct virthba_info *)scsihost->hostdata;
926         if (!virthbainfo)
927                 return 0;       /* even though we errored, treat as success */
928
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         }
936         tmpvdisk = kzalloc(sizeof(*tmpvdisk), GFP_ATOMIC);
937         if (!tmpvdisk)
938                 return 0;
939
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
948 static int
949 virthba_slave_configure(struct scsi_device *scsidev)
950 {
951         return 0;               /* success */
952 }
953
954 static void
955 virthba_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;
962         struct Scsi_Host *scsihost = (struct Scsi_Host *)scsidev->host;
963
964         virthbainfo = (struct virthba_info *)scsihost->hostdata;
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         }
976 }
977
978 /*****************************************************/
979 /* Scsi Cmnd support thread                          */
980 /*****************************************************/
981
982 static void
983 do_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);
991         sd = (struct sense_data *)scsicmd->sense_buffer;
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.... */
1000         for (vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
1001              vdisk->next; vdisk = vdisk->next) {
1002                 if ((scsidev->channel != vdisk->channel) ||
1003                     (scsidev->id != vdisk->id) ||
1004                     (scsidev->lun != vdisk->lun))
1005                         continue;
1006
1007                 if (atomic_read(&vdisk->error_count) < VIRTHBA_ERROR_COUNT) {
1008                         atomic_inc(&vdisk->error_count);
1009                         atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
1010                 }
1011         }
1012 }
1013
1014 static void
1015 do_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;
1027         if ((cmdrsp->scsi.cmnd[0] == INQUIRY) &&
1028             (cmdrsp->scsi.bufflen >= MIN_INQUIRY_RESULT_LEN)) {
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) {
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++) {
1054                         thispage_orig = kmap_atomic(sg_page(sg + i));
1055                         thispage = (void *)((unsigned long)thispage_orig |
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 {
1062                 vdisk = &((struct virthba_info *)scsidev->host->hostdata)->head;
1063                 for ( ; vdisk->next; vdisk = vdisk->next) {
1064                         if ((scsidev->channel != vdisk->channel) ||
1065                             (scsidev->id != vdisk->id) ||
1066                             (scsidev->lun != vdisk->lun))
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) {
1072                                         atomic_set(&vdisk->error_count, 0);
1073                                 }
1074                         }
1075                 }
1076         }
1077 }
1078
1079 static void
1080 complete_scsi_command(struct uiscmdrsp *cmdrsp, struct scsi_cmnd *scsicmd)
1081 {
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
1089         if (scsicmd->scsi_done)
1090                 scsicmd->scsi_done(scsicmd);
1091 }
1092
1093 static inline void
1094 complete_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 */
1098         *(int *)cmdrsp->vdiskmgmt.notifyresult = cmdrsp->vdiskmgmt.result;
1099         wake_up_all((wait_queue_head_t *)cmdrsp->vdiskmgmt.notify);
1100 }
1101
1102 static inline void
1103 complete_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 */
1107         *(int *)cmdrsp->scsitaskmgmt.notifyresult =
1108             cmdrsp->scsitaskmgmt.result;
1109         wake_up_all((wait_queue_head_t *)cmdrsp->scsitaskmgmt.notify);
1110 }
1111
1112 static void
1113 drain_queue(struct virthba_info *virthbainfo, struct chaninfo *dc,
1114             struct uiscmdrsp *cmdrsp)
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);
1123                 if (!spar_channel_client_acquire_os(dc->queueinfo->chan,
1124                                                     "vhba")) {
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);
1132                 spar_channel_client_release_os(dc->queueinfo->chan, "vhba");
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,
1141                                                         (uintptr_t)
1142                                                          cmdrsp->scsi.scsicmd);
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,
1149                                    (uintptr_t)cmdrsp->scsitaskmgmt.scsicmd))
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! */
1157                         cmdrsp->disknotify.v_hba = NULL;
1158                         process_disk_notify(shost, cmdrsp);
1159                 } else if (cmdrsp->cmdtype == CMD_VDISKMGMT_TYPE) {
1160                         if (!del_scsipending_entry(virthbainfo,
1161                                                    (uintptr_t)
1162                                                     cmdrsp->vdiskmgmt.scsicmd))
1163                                 break;
1164                         complete_vdiskmgmt_command(cmdrsp);
1165                 }
1166                 /* cmdrsp is now available for reuse */
1167         }
1168 }
1169
1170 /* main function for the thread that waits for scsi commands to arrive
1171  * in a specified queue
1172  */
1173 static int
1174 process_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);
1180         u64 mask;
1181         unsigned long long rc1;
1182
1183         UIS_DAEMONIZE("vhba_incoming");
1184         /* alloc once and reuse */
1185         cmdrsp = kmalloc(SZ, GFP_ATOMIC);
1186         if (!cmdrsp) {
1187                 complete_and_exit(&dc->threadinfo.has_stopped, 0);
1188                 return 0;
1189         }
1190         mask = ULTRA_CHANNEL_ENABLE_INTS;
1191         while (1) {
1192                 if (kthread_should_stop())
1193                         break;
1194                 wait_event_interruptible_timeout(virthbainfo->rsp_queue,
1195                          (atomic_read(&virthbainfo->interrupt_rcvd) == 1),
1196                                       usecs_to_jiffies(rsltq_wait_usecs));
1197                 atomic_set(&virthbainfo->interrupt_rcvd, 0);
1198                 /* drain queue */
1199                 drain_queue(virthbainfo, dc, cmdrsp);
1200                 rc1 = uisqueue_interlocked_or(virthbainfo->flags_addr, mask);
1201         }
1202
1203         kfree(cmdrsp);
1204
1205         complete_and_exit(&dc->threadinfo.has_stopped, 0);
1206 }
1207
1208 /*****************************************************/
1209 /* Debugfs filesystem functions                      */
1210 /*****************************************************/
1211
1212 static ssize_t info_debugfs_read(struct file *file,
1213                                  char __user *buf, size_t len, loff_t *offset)
1214 {
1215         ssize_t bytes_read = 0;
1216         int str_pos = 0;
1217         u64 phys_flags_addr;
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++) {
1229                 if (!virthbas_open[i].virthbainfo)
1230                         continue;
1231
1232                 virthbainfo = virthbas_open[i].virthbainfo;
1233
1234                 str_pos += scnprintf(vbuf + str_pos,
1235                                 len - str_pos, "max_buff_len:%u\n",
1236                                 max_buff_len);
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
1265 static ssize_t enable_ints_write(struct file *file, const char __user *buffer,
1266                                  size_t count, loff_t *ppos)
1267 {
1268         char buf[4];
1269         int i, new_value;
1270         struct virthba_info *virthbainfo;
1271
1272         u64 __iomem *features_addr;
1273         u64 mask;
1274
1275         if (count >= ARRAY_SIZE(buf))
1276                 return -EINVAL;
1277
1278         buf[count] = '\0';
1279         if (copy_from_user(buf, buffer, count))
1280                 return -EFAULT;
1281
1282         i = kstrtoint(buf, 10, &new_value);
1283
1284         if (i != 0)
1285                 return -EFAULT;
1286
1287         /* set all counts to new_value usually 0 */
1288         for (i = 0; i < VIRTHBASOPENMAX; i++) {
1289                 if (virthbas_open[i].virthbainfo) {
1290                         virthbainfo = virthbas_open[i].virthbainfo;
1291                         features_addr =
1292                                 &virthbainfo->chinfo.queueinfo->chan->features;
1293                         if (new_value == 1) {
1294                                 mask = ~(ULTRA_IO_CHANNEL_IS_POLLING |
1295                                          ULTRA_IO_DRIVER_DISABLES_INTS);
1296                                 uisqueue_interlocked_and(features_addr, mask);
1297                                 mask = ULTRA_IO_DRIVER_ENABLES_INTS;
1298                                 uisqueue_interlocked_or(features_addr, mask);
1299                                 rsltq_wait_usecs = 4000000;
1300                         } else {
1301                                 mask = ~(ULTRA_IO_DRIVER_ENABLES_INTS |
1302                                          ULTRA_IO_DRIVER_DISABLES_INTS);
1303                                 uisqueue_interlocked_and(features_addr, mask);
1304                                 mask = ULTRA_IO_CHANNEL_IS_POLLING;
1305                                 uisqueue_interlocked_or(features_addr, mask);
1306                                 rsltq_wait_usecs = 4000;
1307                         }
1308                 }
1309         }
1310         return count;
1311 }
1312
1313 /* As per VirtpciFunc returns 1 for success and 0 for failure */
1314 static int
1315 virthba_serverup(struct virtpci_dev *virtpcidev)
1316 {
1317         struct virthba_info *virthbainfo =
1318             (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
1319                                      scsihost)->hostdata;
1320
1321         if (!virthbainfo->serverdown)
1322                 return 1;
1323
1324         if (virthbainfo->serverchangingstate)
1325                 return 0;
1326
1327         virthbainfo->serverchangingstate = true;
1328         /* Must transition channel to ATTACHED state BEFORE we
1329          * can start using the device again
1330          */
1331         SPAR_CHANNEL_CLIENT_TRANSITION(virthbainfo->chinfo.queueinfo->chan,
1332                                        dev_name(&virtpcidev->generic_dev),
1333                                        CHANNELCLI_ATTACHED, NULL);
1334
1335         /* Start Processing the IOVM Response Queue Again */
1336         if (!uisthread_start(&virthbainfo->chinfo.threadinfo,
1337                              process_incoming_rsps,
1338                              virthbainfo, "vhba_incoming")) {
1339                 return 0;
1340         }
1341         virthbainfo->serverdown = false;
1342         virthbainfo->serverchangingstate = false;
1343
1344         return 1;
1345 }
1346
1347 static void
1348 virthba_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++) {
1369                 pendingdel = &virthbainfo->pending[i];
1370                 switch (pendingdel->cmdtype) {
1371                 case CMD_SCSI_TYPE:
1372                         scsicmd = (struct scsi_cmnd *)pendingdel->sent;
1373                         scsicmd->result = DID_RESET << 16;
1374                         if (scsicmd->scsi_done)
1375                                 scsicmd->scsi_done(scsicmd);
1376                         break;
1377                 case CMD_SCSITASKMGMT_TYPE:
1378                         cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
1379                         wake_up_all((wait_queue_head_t *)
1380                                     cmdrsp->scsitaskmgmt.notify);
1381                         *(int *)cmdrsp->scsitaskmgmt.notifyresult =
1382                                 TASK_MGMT_FAILED;
1383                         break;
1384                 case CMD_VDISKMGMT_TYPE:
1385                         cmdrsp = (struct uiscmdrsp *)pendingdel->sent;
1386                         *(int *)cmdrsp->vdiskmgmt.notifyresult =
1387                             VDISK_MGMT_FAILED;
1388                         wake_up_all((wait_queue_head_t *)
1389                                     cmdrsp->vdiskmgmt.notify);
1390                         break;
1391                 default:
1392                         break;
1393                 }
1394                 pendingdel->cmdtype = 0;
1395                 pendingdel->sent = NULL;
1396         }
1397         spin_unlock_irqrestore(&virthbainfo->privlock, flags);
1398
1399         virtpcidev = virthbainfo->virtpcidev;
1400
1401         virthbainfo->serverdown = true;
1402         virthbainfo->serverchangingstate = false;
1403         /* Return the ServerDown response to Command */
1404         visorchipset_device_pause_response(virtpcidev->bus_no,
1405                                            virtpcidev->device_no, 0);
1406 }
1407
1408 /* As per VirtpciFunc returns 1 for success and 0 for failure */
1409 static int
1410 virthba_serverdown(struct virtpci_dev *virtpcidev, u32 state)
1411 {
1412         int stat = 1;
1413
1414         struct virthba_info *virthbainfo =
1415             (struct virthba_info *)((struct Scsi_Host *)virtpcidev->scsi.
1416                                      scsihost)->hostdata;
1417
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) {
1423                 stat = 0;
1424         }
1425
1426         return stat;
1427 }
1428
1429 /*****************************************************/
1430 /* Module Init & Exit functions                      */
1431 /*****************************************************/
1432
1433 static int __init
1434 virthba_parse_line(char *str)
1435 {
1436         return 1;
1437 }
1438
1439 static void __init
1440 virthba_parse_options(char *line)
1441 {
1442         char *next = line;
1443
1444         POSTCODE_LINUX_2(VHBA_CREATE_ENTRY_PC, POSTCODE_SEVERITY_INFO);
1445         if (!line || !*line)
1446                 return;
1447         while ((line = next)) {
1448                 next = strchr(line, ' ');
1449                 if (next)
1450                         *next++ = 0;
1451                 virthba_parse_line(line);
1452         }
1453
1454         POSTCODE_LINUX_2(VHBA_CREATE_EXIT_PC, POSTCODE_SEVERITY_INFO);
1455 }
1456
1457 static int __init
1458 virthba_mod_init(void)
1459 {
1460         int error;
1461         int i;
1462
1463         if (!unisys_spar_platform)
1464                 return -ENODEV;
1465
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) {
1471                 POSTCODE_LINUX_3(VHBA_CREATE_FAILURE_PC, error,
1472                                  POSTCODE_SEVERITY_ERR);
1473         } else {
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,
1477                                     NULL, &debugfs_info_fops);
1478                 debugfs_create_u32("rqwait_usecs", S_IRUSR | S_IWUSR,
1479                                    virthba_debugfs_dir, &rsltq_wait_usecs);
1480                 debugfs_create_file("enable_ints", S_IWUSR,
1481                                     virthba_debugfs_dir, NULL,
1482                                     &debugfs_enable_ints_fops);
1483                 /* Initialize dar_work_queue */
1484                 INIT_WORK(&dar_work_queue, do_disk_add_remove);
1485                 spin_lock_init(&dar_work_queue_lock);
1486
1487                 /* clear out array */
1488                 for (i = 0; i < VIRTHBASOPENMAX; i++)
1489                         virthbas_open[i].virthbainfo = NULL;
1490                 /* Initialize the serverdown workqueue */
1491                 virthba_serverdown_workqueue =
1492                     create_singlethread_workqueue("virthba_serverdown");
1493                 if (!virthba_serverdown_workqueue) {
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);
1501         return error;
1502 }
1503
1504 static ssize_t
1505 virthba_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
1519 static ssize_t
1520 virthba_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
1538 static CLASS_DEVICE_ATTR(acquire_lun, S_IWUSR, NULL, virthba_acquire_lun);
1539 static CLASS_DEVICE_ATTR(release_lun, S_IWUSR, NULL, virthba_release_lun);
1540
1541 static DEVICE_ATTRIBUTE *virthba_shost_attrs[] = {
1542         &class_device_attr_acquire_lun,
1543         &class_device_attr_release_lun,
1544         NULL
1545 };
1546
1547 static void __exit
1548 virthba_mod_exit(void)
1549 {
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
1558         debugfs_remove_recursive(virthba_debugfs_dir);
1559 }
1560
1561 /* specify function to be run at module insertion time */
1562 module_init(virthba_mod_init);
1563
1564 /* specify function to be run when module is removed */
1565 module_exit(virthba_mod_exit);
1566
1567 MODULE_LICENSE("GPL");
1568 MODULE_AUTHOR("Usha Srinivasan");
1569 MODULE_ALIAS("uisvirthba");
1570         /* this is extracted during depmod and kept in modules.dep */
1571 /* module parameter */
1572 module_param(virthba_options, charp, S_IRUGO);