3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
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.
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
20 #include <linux/kernel.h>
21 #ifdef CONFIG_MODVERSIONS
22 #include <config/modversions.h>
25 #include "diagnostics/appos_subsystems.h"
27 #include "commontypes.h"
28 #include "vbuschannel.h"
29 #include "vbushelper.h"
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/pci.h>
33 #include <linux/device.h>
34 #include <linux/list.h>
35 #include <linux/slab.h>
36 #include <linux/mod_devicetable.h>
37 #include <linux/if_ether.h>
38 #include <linux/version.h>
39 #include <linux/debugfs.h>
41 #include "guestlinuxdebug.h"
42 #include "timskmodutils.h"
44 struct driver_private
{
46 struct klist klist_devices
;
47 struct klist_node knode_bus
;
48 struct module_kobject
*mkobj
;
49 struct device_driver
*driver
;
51 #define to_driver(obj) container_of(obj, struct driver_private, kobj)
53 /* bus_id went away in 2.6.30 - the size was 20 bytes, so we'll define
54 * it ourselves, and a macro to make getting the field a bit simpler.
57 #define BUS_ID_SIZE 20
60 #define BUS_ID(x) dev_name(x)
62 /* MAX_BUF = 4 busses x ( 32 devices/bus + 1 busline) x 80 characters
63 * = 10,560 bytes ~ 2^14 = 16,384 bytes
69 /* this is shorter than using __FILE__ (full path name) in
70 * debug/info/error messages
72 #define CURRENT_FILE_PC VIRT_PCI_PC_virtpci_c
73 #define __MYFILE__ "virtpci.c"
75 #define VIRTPCI_VERSION "01.00"
77 /*****************************************************/
78 /* Forward declarations */
79 /*****************************************************/
81 static int delete_vbus_device(struct device
*vbus
, void *data
);
82 static int match_busid(struct device
*dev
, void *data
);
83 static void virtpci_bus_release(struct device
*dev
);
84 static void virtpci_device_release(struct device
*dev
);
85 static int virtpci_device_add(struct device
*parentbus
, int devtype
,
86 struct add_virt_guestpart
*addparams
,
87 struct scsi_adap_info
*scsi
,
88 struct net_adap_info
*net
);
89 static int virtpci_device_del(struct device
*parentbus
, int devtype
,
90 struct vhba_wwnn
*wwnn
, unsigned char macaddr
[]);
91 static int virtpci_device_serverdown(struct device
*parentbus
, int devtype
,
92 struct vhba_wwnn
*wwnn
,
93 unsigned char macaddr
[]);
94 static int virtpci_device_serverup(struct device
*parentbus
, int devtype
,
95 struct vhba_wwnn
*wwnn
,
96 unsigned char macaddr
[]);
97 static ssize_t
virtpci_driver_attr_show(struct kobject
*kobj
,
98 struct attribute
*attr
, char *buf
);
99 static ssize_t
virtpci_driver_attr_store(struct kobject
*kobj
,
100 struct attribute
*attr
,
101 const char *buf
, size_t count
);
102 static int virtpci_bus_match(struct device
*dev
, struct device_driver
*drv
);
103 static int virtpci_uevent(struct device
*dev
, struct kobj_uevent_env
*env
);
104 static int virtpci_device_suspend(struct device
*dev
, pm_message_t state
);
105 static int virtpci_device_resume(struct device
*dev
);
106 static int virtpci_device_probe(struct device
*dev
);
107 static int virtpci_device_remove(struct device
*dev
);
109 static ssize_t
info_debugfs_read(struct file
*file
, char __user
*buf
,
110 size_t len
, loff_t
*offset
);
112 static const struct file_operations debugfs_info_fops
= {
113 .read
= info_debugfs_read
,
116 /*****************************************************/
118 /*****************************************************/
120 /* methods in bus_type struct allow the bus code to serve as an
121 * intermediary between the device core and individual device core and
124 static struct bus_type virtpci_bus_type
= {
125 .name
= "uisvirtpci",
126 .match
= virtpci_bus_match
,
127 .uevent
= virtpci_uevent
,
128 .suspend
= virtpci_device_suspend
,
129 .resume
= virtpci_device_resume
,
132 static struct device virtpci_rootbus_device
= {
133 .init_name
= "vbusroot", /* root bus */
134 .release
= virtpci_bus_release
137 /* filled in with info about parent chipset driver when we register with it */
138 static ULTRA_VBUS_DEVICEINFO Chipset_DriverInfo
;
140 static const struct sysfs_ops virtpci_driver_sysfs_ops
= {
141 .show
= virtpci_driver_attr_show
,
142 .store
= virtpci_driver_attr_store
,
145 static struct kobj_type virtpci_driver_kobj_type
= {
146 .sysfs_ops
= &virtpci_driver_sysfs_ops
,
149 static struct virtpci_dev
*VpcidevListHead
;
150 static DEFINE_RWLOCK(VpcidevListLock
);
152 /* filled in with info about this driver, wrt it servicing client busses */
153 static ULTRA_VBUS_DEVICEINFO Bus_DriverInfo
;
155 /*****************************************************/
156 /* debugfs entries */
157 /*****************************************************/
158 /* dentry is used to create the debugfs entry directory
161 static struct dentry
*virtpci_debugfs_dir
;
163 struct virtpci_busdev
{
164 struct device virtpci_bus_device
;
167 /*****************************************************/
168 /* Local functions */
169 /*****************************************************/
172 int WAIT_FOR_IO_CHANNEL(ULTRA_IO_CHANNEL_PROTOCOL __iomem
*chanptr
)
177 if (ULTRA_CHANNEL_SERVER_READY(&chanptr
->ChannelHeader
))
179 UIS_THREAD_WAIT_SEC(1);
185 /* Write the contents of <info> to the ULTRA_VBUS_CHANNEL_PROTOCOL.ChpInfo. */
186 static int write_vbus_chpInfo(ULTRA_VBUS_CHANNEL_PROTOCOL
*chan
,
187 ULTRA_VBUS_DEVICEINFO
*info
)
191 LOGERR("vbus channel not present");
194 off
= sizeof(ULTRA_CHANNEL_PROTOCOL
) + chan
->HdrInfo
.chpInfoByteOffset
;
195 if (chan
->HdrInfo
.chpInfoByteOffset
== 0) {
196 LOGERR("vbus channel not used, because chpInfoByteOffset == 0");
199 memcpy(((u8
*) (chan
)) + off
, info
, sizeof(*info
));
203 /* Write the contents of <info> to the ULTRA_VBUS_CHANNEL_PROTOCOL.BusInfo. */
204 static int write_vbus_busInfo(ULTRA_VBUS_CHANNEL_PROTOCOL
*chan
,
205 ULTRA_VBUS_DEVICEINFO
*info
)
209 LOGERR("vbus channel not present");
212 off
= sizeof(ULTRA_CHANNEL_PROTOCOL
) + chan
->HdrInfo
.busInfoByteOffset
;
213 if (chan
->HdrInfo
.busInfoByteOffset
== 0) {
214 LOGERR("vbus channel not used, because busInfoByteOffset == 0");
217 memcpy(((u8
*) (chan
)) + off
, info
, sizeof(*info
));
221 /* Write the contents of <info> to the
222 * ULTRA_VBUS_CHANNEL_PROTOCOL.DevInfo[<devix>].
225 write_vbus_devInfo(ULTRA_VBUS_CHANNEL_PROTOCOL
*chan
,
226 ULTRA_VBUS_DEVICEINFO
*info
, int devix
)
230 LOGERR("vbus channel not present");
234 (sizeof(ULTRA_CHANNEL_PROTOCOL
) +
235 chan
->HdrInfo
.devInfoByteOffset
) +
236 (chan
->HdrInfo
.deviceInfoStructBytes
* devix
);
237 if (chan
->HdrInfo
.devInfoByteOffset
== 0) {
238 LOGERR("vbus channel not used, because devInfoByteOffset == 0");
241 memcpy(((u8
*) (chan
)) + off
, info
, sizeof(*info
));
246 * returns 0 failure, 1 success,
248 static int add_vbus(struct add_vbus_guestpart
*addparams
)
252 vbus
= kzalloc(sizeof(struct device
), GFP_ATOMIC
);
254 POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
258 dev_set_name(vbus
, "vbus%d", addparams
->busNo
);
259 vbus
->release
= virtpci_bus_release
;
260 vbus
->parent
= &virtpci_rootbus_device
; /* root bus is parent */
261 vbus
->bus
= &virtpci_bus_type
; /* bus type */
262 vbus
->platform_data
= (__force
void *)addparams
->chanptr
;
264 /* register a virt bus device -
265 * this bus shows up under /sys/devices with .name value
266 * "virtpci%d" any devices added to this bus then show up under
267 * /sys/devices/virtpci0
269 ret
= device_register(vbus
);
271 LOGERR("device_register FAILED:%d\n", ret
);
272 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
275 write_vbus_chpInfo(vbus
->platform_data
/* chanptr */ ,
276 &Chipset_DriverInfo
);
277 write_vbus_busInfo(vbus
->platform_data
/* chanptr */ , &Bus_DriverInfo
);
278 LOGINF("Added vbus %d; device %s created successfully\n",
279 addparams
->busNo
, BUS_ID(vbus
));
280 POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
284 /* for CHANSOCK wwwnn/max are AUTO-GENERATED; for normal channels,
285 * wwnn/max are in the channel header.
287 #define GET_SCSIADAPINFO_FROM_CHANPTR(chanptr) { \
288 memcpy_fromio(&scsi.wwnn, \
289 &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
290 chanptr)->vhba.wwnn, \
291 sizeof(struct vhba_wwnn)); \
292 memcpy_fromio(&scsi.max, \
293 &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
294 chanptr)->vhba.max, \
295 sizeof(struct vhba_config_max)); \
298 /* find bus device with the busid that matches - match_busid matches bus_id */
299 #define GET_BUS_DEV(busno) { \
300 sprintf(busid, "vbus%d", busno); \
301 vbus = bus_find_device(&virtpci_bus_type, NULL, \
302 (void *)busid, match_busid); \
304 LOGERR("**** FAILED to find vbus %s\n", busid); \
310 * returns 0 failure, 1 success,
312 static int add_vhba(struct add_virt_guestpart
*addparams
)
315 struct scsi_adap_info scsi
;
317 unsigned char busid
[BUS_ID_SIZE
];
319 POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
320 if (!WAIT_FOR_IO_CHANNEL
321 ((ULTRA_IO_CHANNEL_PROTOCOL __iomem
*) addparams
->chanptr
)) {
322 LOGERR("Timed out. Channel not ready\n");
323 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
327 GET_SCSIADAPINFO_FROM_CHANPTR(addparams
->chanptr
);
329 GET_BUS_DEV(addparams
->busNo
);
331 LOGINF("Adding vhba wwnn:%x:%x config:%d-%d-%d-%d chanptr:%p\n",
332 scsi
.wwnn
.wwnn1
, scsi
.wwnn
.wwnn2
,
333 scsi
.max
.max_channel
, scsi
.max
.max_id
, scsi
.max
.max_lun
,
334 scsi
.max
.cmd_per_lun
, addparams
->chanptr
);
335 i
= virtpci_device_add(vbus
, VIRTHBA_TYPE
, addparams
, &scsi
, NULL
);
337 LOGINF("Added vhba wwnn:%x:%x chanptr:%p\n", scsi
.wwnn
.wwnn1
,
338 scsi
.wwnn
.wwnn2
, addparams
->chanptr
);
339 POSTCODE_LINUX_3(VPCI_CREATE_EXIT_PC
, i
,
340 POSTCODE_SEVERITY_INFO
);
346 /* for CHANSOCK macaddr is AUTO-GENERATED; for normal channels,
347 * macaddr is in the channel header.
349 #define GET_NETADAPINFO_FROM_CHANPTR(chanptr) { \
350 memcpy_fromio(net.mac_addr, \
351 ((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
352 chanptr)->vnic.macaddr, \
355 readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
356 chanptr)->vnic.num_rcv_bufs); \
357 net.mtu = readl(&((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
358 chanptr)->vnic.mtu); \
359 memcpy_fromio(&net.zoneGuid, \
360 &((ULTRA_IO_CHANNEL_PROTOCOL __iomem *) \
361 chanptr)->vnic.zoneGuid, \
366 * returns 0 failure, 1 success,
369 add_vnic(struct add_virt_guestpart
*addparams
)
372 struct net_adap_info net
;
374 unsigned char busid
[BUS_ID_SIZE
];
376 POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
377 if (!WAIT_FOR_IO_CHANNEL
378 ((ULTRA_IO_CHANNEL_PROTOCOL __iomem
*) addparams
->chanptr
)) {
379 LOGERR("Timed out, channel not ready\n");
380 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
384 GET_NETADAPINFO_FROM_CHANPTR(addparams
->chanptr
);
386 GET_BUS_DEV(addparams
->busNo
);
388 LOGINF("Adding vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x rcvbufs:%d mtu:%d chanptr:%p%pUL\n",
389 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2], net
.mac_addr
[3],
390 net
.mac_addr
[4], net
.mac_addr
[5], net
.num_rcv_bufs
, net
.mtu
,
391 addparams
->chanptr
, &net
.zoneGuid
);
392 i
= virtpci_device_add(vbus
, VIRTNIC_TYPE
, addparams
, NULL
, &net
);
394 LOGINF("Added vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
395 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
396 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
397 POSTCODE_LINUX_3(VPCI_CREATE_EXIT_PC
, i
,
398 POSTCODE_SEVERITY_INFO
);
405 * returns 0 failure, 1 success,
408 delete_vbus(struct del_vbus_guestpart
*delparams
)
411 unsigned char busid
[BUS_ID_SIZE
];
413 GET_BUS_DEV(delparams
->busNo
);
414 /* ensure that bus has no devices? -- TBD */
415 LOGINF("Deleting %s\n", BUS_ID(vbus
));
416 if (delete_vbus_device(vbus
, NULL
))
417 return 0; /* failure */
418 LOGINF("Deleted vbus %d\n", delparams
->busNo
);
423 delete_vbus_device(struct device
*vbus
, void *data
)
425 int checkforroot
= (data
!= NULL
);
426 struct device
*pDev
= &virtpci_rootbus_device
;
428 if ((checkforroot
) && match_busid(vbus
, (void *) BUS_ID(pDev
))) {
429 /* skip it - don't delete root bus */
430 LOGINF("skipping root bus\n");
431 return 0; /* pretend no error */
433 LOGINF("Calling unregister for %s\n", BUS_ID(vbus
));
434 device_unregister(vbus
);
436 LOGINF("VBus unregister and freed\n");
437 return 0; /* no error */
441 * returns 0 failure, 1 success,
443 static int pause_vhba(struct pause_virt_guestpart
*pauseparams
)
446 struct scsi_adap_info scsi
;
448 GET_SCSIADAPINFO_FROM_CHANPTR(pauseparams
->chanptr
);
450 LOGINF("Pausing vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
, scsi
.wwnn
.wwnn2
);
451 i
= virtpci_device_serverdown(NULL
/*no parent bus */ , VIRTHBA_TYPE
,
454 LOGINF("Paused vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
,
460 * returns 0 failure, 1 success,
462 static int pause_vnic(struct pause_virt_guestpart
*pauseparams
)
465 struct net_adap_info net
;
467 GET_NETADAPINFO_FROM_CHANPTR(pauseparams
->chanptr
);
469 LOGINF("Pausing vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
470 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
471 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
472 i
= virtpci_device_serverdown(NULL
/*no parent bus */ , VIRTNIC_TYPE
,
475 LOGINF(" Paused vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
476 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
477 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
483 * returns 0 failure, 1 success,
485 static int resume_vhba(struct resume_virt_guestpart
*resumeparams
)
488 struct scsi_adap_info scsi
;
490 GET_SCSIADAPINFO_FROM_CHANPTR(resumeparams
->chanptr
);
492 LOGINF("Resuming vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
, scsi
.wwnn
.wwnn2
);
493 i
= virtpci_device_serverup(NULL
/*no parent bus */ , VIRTHBA_TYPE
,
496 LOGINF("Resumed vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
,
502 * returns 0 failure, 1 success,
505 resume_vnic(struct resume_virt_guestpart
*resumeparams
)
508 struct net_adap_info net
;
510 GET_NETADAPINFO_FROM_CHANPTR(resumeparams
->chanptr
);
512 LOGINF("Resuming vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
513 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
514 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
515 i
= virtpci_device_serverup(NULL
/*no parent bus */ , VIRTNIC_TYPE
,
518 LOGINF(" Resumed vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
519 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
520 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
526 * returns 0 failure, 1 success,
528 static int delete_vhba(struct del_virt_guestpart
*delparams
)
531 struct scsi_adap_info scsi
;
533 GET_SCSIADAPINFO_FROM_CHANPTR(delparams
->chanptr
);
535 LOGINF("Deleting vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
, scsi
.wwnn
.wwnn2
);
536 i
= virtpci_device_del(NULL
/*no parent bus */ , VIRTHBA_TYPE
,
539 LOGINF("Deleted vhba wwnn:%x:%x\n", scsi
.wwnn
.wwnn1
,
547 * returns 0 failure, 1 success,
549 static int delete_vnic(struct del_virt_guestpart
*delparams
)
552 struct net_adap_info net
;
554 GET_NETADAPINFO_FROM_CHANPTR(delparams
->chanptr
);
556 LOGINF("Deleting vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
557 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
558 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
559 i
= virtpci_device_del(NULL
/*no parent bus */ , VIRTNIC_TYPE
, NULL
,
562 LOGINF("Deleted vnic macaddr:%02x:%02x:%02x:%02x:%02x:%02x\n",
563 net
.mac_addr
[0], net
.mac_addr
[1], net
.mac_addr
[2],
564 net
.mac_addr
[3], net
.mac_addr
[4], net
.mac_addr
[5]);
569 #define DELETE_ONE_VPCIDEV(vpcidev) { \
570 LOGINF("calling device_unregister:%p\n", &vpcidev->generic_dev); \
571 device_unregister(&vpcidev->generic_dev); \
572 LOGINF("Deleted %p\n", vpcidev); \
576 /* deletes all vhbas and vnics
577 * returns 0 failure, 1 success,
579 static void delete_all(void)
583 struct virtpci_dev
*tmpvpcidev
, *nextvpcidev
;
585 /* delete the entire vhba/vnic list in one shot */
586 write_lock_irqsave(&VpcidevListLock
, flags
);
587 tmpvpcidev
= VpcidevListHead
;
588 VpcidevListHead
= NULL
;
589 write_unlock_irqrestore(&VpcidevListLock
, flags
);
591 /* delete one vhba/vnic at a time */
593 nextvpcidev
= tmpvpcidev
->next
;
594 /* delete the vhba/vnic at tmpvpcidev */
595 DELETE_ONE_VPCIDEV(tmpvpcidev
);
596 tmpvpcidev
= nextvpcidev
;
599 LOGINF("Deleted %d vhbas/vnics.\n", count
);
601 /* now delete each vbus */
603 (&virtpci_bus_type
, NULL
, (void *) 1, delete_vbus_device
))
604 LOGERR("delete of all vbus failed\n");
607 /* deletes all vnics or vhbas
608 * returns 0 failure, 1 success,
610 static int delete_all_virt(VIRTPCI_DEV_TYPE devtype
, struct del_vbus_guestpart
*delparams
)
613 unsigned char busid
[BUS_ID_SIZE
];
616 GET_BUS_DEV(delparams
->busNo
);
618 if ((devtype
!= VIRTHBA_TYPE
) && (devtype
!= VIRTNIC_TYPE
)) {
619 LOGERR("**** FAILED to delete all devices; devtype:%d not vhba:%d or vnic:%d\n",
620 devtype
, VIRTHBA_TYPE
, VIRTNIC_TYPE
);
624 LOGINF("Deleting all %s in vbus %s\n",
625 devtype
== VIRTHBA_TYPE
? "vhbas" : "vnics", busid
);
626 /* delete all vhbas/vnics */
627 i
= virtpci_device_del(vbus
, devtype
, NULL
, NULL
);
629 LOGINF("Deleted %d %s\n", i
,
630 devtype
== VIRTHBA_TYPE
? "vhbas" : "vnics");
634 static int virtpci_ctrlchan_func(struct guest_msgs
*msg
)
636 switch (msg
->msgtype
) {
638 return add_vbus(&msg
->add_vbus
);
640 return add_vhba(&msg
->add_vhba
);
642 return add_vnic(&msg
->add_vnic
);
644 return delete_vbus(&msg
->del_vbus
);
646 return delete_vhba(&msg
->del_vhba
);
648 return delete_vnic(&msg
->del_vhba
);
649 case GUEST_DEL_ALL_VHBAS
:
650 return delete_all_virt(VIRTHBA_TYPE
, &msg
->del_all_vhbas
);
651 case GUEST_DEL_ALL_VNICS
:
652 return delete_all_virt(VIRTNIC_TYPE
, &msg
->del_all_vnics
);
653 case GUEST_DEL_ALL_VBUSES
:
656 case GUEST_PAUSE_VHBA
:
657 return pause_vhba(&msg
->pause_vhba
);
658 case GUEST_PAUSE_VNIC
:
659 return pause_vnic(&msg
->pause_vnic
);
660 case GUEST_RESUME_VHBA
:
661 return resume_vhba(&msg
->resume_vhba
);
662 case GUEST_RESUME_VNIC
:
663 return resume_vnic(&msg
->resume_vnic
);
665 LOGERR("invalid message type %d.\n", msg
->msgtype
);
670 /* same as driver_helper in bus.c linux */
671 static int match_busid(struct device
*dev
, void *data
)
673 const char *name
= data
;
675 if (strcmp(name
, BUS_ID(dev
)) == 0)
680 /*****************************************************/
682 /*****************************************************/
684 static const struct pci_device_id
*
685 virtpci_match_device(const struct pci_device_id
*ids
,
686 const struct virtpci_dev
*dev
)
688 while (ids
->vendor
|| ids
->subvendor
|| ids
->class_mask
) {
689 DBGINF("ids->vendor:%x dev->vendor:%x ids->device:%x dev->device:%x\n",
690 ids
->vendor
, dev
->vendor
, ids
->device
, dev
->device
);
692 if ((ids
->vendor
== dev
->vendor
)
693 && (ids
->device
== dev
->device
))
701 /* NOTE: !!!!!! This function is called when a new device is added
702 * for this bus. Or, it is called for existing devices when a new
703 * driver is added for this bus. It returns nonzero if a given device
704 * can be handled by the given driver.
706 static int virtpci_bus_match(struct device
*dev
, struct device_driver
*drv
)
708 struct virtpci_dev
*virtpcidev
= device_to_virtpci_dev(dev
);
709 struct virtpci_driver
*virtpcidrv
= driver_to_virtpci_driver(drv
);
712 DBGINF("In virtpci_bus_match dev->bus_id:%s drv->name:%s\n",
713 dev
->bus_id
, drv
->name
);
715 /* check ids list for a match */
716 if (virtpci_match_device(virtpcidrv
->id_table
, virtpcidev
))
719 DBGINF("returning match:%d\n", match
);
720 return match
; /* 0 - no match; 1 - yes it matches */
723 static int virtpci_uevent(struct device
*dev
, struct kobj_uevent_env
*env
)
725 DBGINF("In virtpci_hotplug\n");
726 /* add variables to the environment prior to the generation of
727 * hotplug events to user space
729 if (add_uevent_var(env
, "VIRTPCI_VERSION=%s", VIRTPCI_VERSION
))
734 static int virtpci_device_suspend(struct device
*dev
, pm_message_t state
)
736 DBGINF("In virtpci_device_suspend -NYI ****\n");
740 static int virtpci_device_resume(struct device
*dev
)
742 DBGINF("In virtpci_device_resume -NYI ****\n");
746 /* For a child device just created on a client bus, fill in
747 * information about the driver that is controlling this device into
748 * the the appropriate slot within the vbus channel of the bus
751 static void fix_vbus_devInfo(struct device
*dev
, int devNo
, int devType
,
752 struct virtpci_driver
*virtpcidrv
)
756 ULTRA_VBUS_DEVICEINFO devInfo
;
760 LOGERR("%s dev is NULL", __func__
);
764 LOGERR("%s driver is NULL", __func__
);
769 LOGERR("%s dev has no parent bus", __func__
);
772 pChan
= vbus
->platform_data
;
774 LOGERR("%s dev bus has no channel", __func__
);
778 case PCI_DEVICE_ID_VIRTHBA
:
781 case PCI_DEVICE_ID_VIRTNIC
:
788 BusDeviceInfo_Init(&devInfo
, stype
,
792 write_vbus_devInfo(pChan
, &devInfo
, devNo
);
794 /* Re-write bus+chipset info, because it is possible that this
795 * was previously written by our good counterpart, visorbus.
797 write_vbus_chpInfo(pChan
, &Chipset_DriverInfo
);
798 write_vbus_busInfo(pChan
, &Bus_DriverInfo
);
801 /* This function is called to query the existence of a specific device
802 * and whether this driver can work with it. It should return -ENODEV
803 * in case of failure.
805 static int virtpci_device_probe(struct device
*dev
)
807 struct virtpci_dev
*virtpcidev
= device_to_virtpci_dev(dev
);
808 struct virtpci_driver
*virtpcidrv
=
809 driver_to_virtpci_driver(dev
->driver
);
810 const struct pci_device_id
*id
;
813 LOGINF("In virtpci_device_probe dev:%p virtpcidev:%p virtpcidrv:%p\n",
814 dev
, virtpcidev
, virtpcidrv
); /* VERBOSE/DEBUG ? */
815 POSTCODE_LINUX_2(VPCI_PROBE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
816 /* static match and static probe vs dynamic match & dynamic
817 * probe - do we care?.
819 if (!virtpcidrv
->id_table
)
822 id
= virtpci_match_device(virtpcidrv
->id_table
, virtpcidev
);
826 /* increment reference count */
829 /* if virtpcidev is not already claimed & probe function is
832 if (!virtpcidev
->mydriver
&& virtpcidrv
->probe
) {
833 /* call the probe function - virthba or virtnic probe
834 * is what it should be
836 error
= virtpcidrv
->probe(virtpcidev
, id
);
838 fix_vbus_devInfo(dev
, virtpcidev
->deviceNo
,
839 virtpcidev
->device
, virtpcidrv
);
840 virtpcidev
->mydriver
= virtpcidrv
;
841 POSTCODE_LINUX_2(VPCI_PROBE_EXIT_PC
,
842 POSTCODE_SEVERITY_INFO
);
846 POSTCODE_LINUX_2(VPCI_PROBE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
847 return error
; /* -ENODEV for probe failure */
850 static int virtpci_device_remove(struct device
*dev_
)
852 /* dev_ passed in is the HBA device which we called
853 * generic_dev in our virtpcidev struct
855 struct virtpci_dev
*virtpcidev
= device_to_virtpci_dev(dev_
);
856 struct virtpci_driver
*virtpcidrv
= virtpcidev
->mydriver
;
857 LOGINF("In virtpci_device_remove bus_id:%s dev_:%p virtpcidev:%p dev->driver:%p drivername:%s\n",
858 BUS_ID(dev_
), dev_
, virtpcidev
, dev_
->driver
,
859 dev_
->driver
->name
); /* VERBOSE/DEBUG */
861 /* TEMP: assuming we have only one such driver for now */
862 if (virtpcidrv
->remove
)
863 virtpcidrv
->remove(virtpcidev
);
864 virtpcidev
->mydriver
= NULL
;
867 DBGINF("calling putdevice\n");
874 /*****************************************************/
876 /*****************************************************/
878 static void virtpci_bus_release(struct device
*dev
)
880 /* this function is called when the last reference to the
883 DBGINF("In virtpci_bus_release\n");
884 /* what else is supposed to happen here? */
887 /*****************************************************/
888 /* Adapter functions */
889 /*****************************************************/
891 static int virtpci_device_add(struct device
*parentbus
, int devtype
,
892 struct add_virt_guestpart
*addparams
,
893 struct scsi_adap_info
*scsi
, /* NULL for VNIC add */
894 struct net_adap_info
*net
/* NULL for VHBA add */)
896 struct virtpci_dev
*virtpcidev
= NULL
;
897 struct virtpci_dev
*tmpvpcidev
= NULL
, *prev
;
900 ULTRA_IO_CHANNEL_PROTOCOL __iomem
*pIoChan
= NULL
;
903 LOGINF("virtpci_device_add parentbus:%p chanptr:%p\n", parentbus
,
906 POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
908 if ((devtype
!= VIRTHBA_TYPE
) && (devtype
!= VIRTNIC_TYPE
)) {
909 LOGERR("**** FAILED to add device; devtype:%d not vhba:%d or vnic:%d\n",
910 devtype
, VIRTHBA_TYPE
, VIRTNIC_TYPE
);
911 POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC
, devtype
,
912 POSTCODE_SEVERITY_ERR
);
916 /* add a Virtual Device */
917 virtpcidev
= kzalloc(sizeof(struct virtpci_dev
), GFP_ATOMIC
);
918 if (virtpcidev
== NULL
) {
919 LOGERR("can't add device - malloc FALLED\n");
920 POSTCODE_LINUX_2(MALLOC_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
924 /* initialize stuff unique to virtpci_dev struct */
925 virtpcidev
->devtype
= devtype
;
926 if (devtype
== VIRTHBA_TYPE
) {
927 virtpcidev
->device
= PCI_DEVICE_ID_VIRTHBA
;
928 virtpcidev
->scsi
= *scsi
;
930 virtpcidev
->device
= PCI_DEVICE_ID_VIRTNIC
;
931 virtpcidev
->net
= *net
;
933 virtpcidev
->vendor
= PCI_VENDOR_ID_UNISYS
;
934 virtpcidev
->busNo
= addparams
->busNo
;
935 virtpcidev
->deviceNo
= addparams
->deviceNo
;
937 virtpcidev
->queueinfo
.chan
= addparams
->chanptr
;
938 virtpcidev
->queueinfo
.send_int_if_needed
= NULL
;
940 /* Set up safe queue... */
941 pIoChan
= (ULTRA_IO_CHANNEL_PROTOCOL __iomem
*)
942 virtpcidev
->queueinfo
.chan
;
944 virtpcidev
->intr
= addparams
->intr
;
946 /* initialize stuff in the device portion of the struct */
947 virtpcidev
->generic_dev
.bus
= &virtpci_bus_type
;
948 virtpcidev
->generic_dev
.parent
= parentbus
;
949 virtpcidev
->generic_dev
.release
= virtpci_device_release
;
951 dev_set_name(&virtpcidev
->generic_dev
, "%x:%x",
952 addparams
->busNo
, addparams
->deviceNo
);
954 /* add the vhba/vnic to virtpci device list - but check for
955 * duplicate wwnn/macaddr first
957 write_lock_irqsave(&VpcidevListLock
, flags
);
958 for (tmpvpcidev
= VpcidevListHead
; tmpvpcidev
;
959 tmpvpcidev
= tmpvpcidev
->next
) {
960 if (devtype
== VIRTHBA_TYPE
) {
961 if ((tmpvpcidev
->scsi
.wwnn
.wwnn1
== scsi
->wwnn
.wwnn1
) &&
962 (tmpvpcidev
->scsi
.wwnn
.wwnn2
== scsi
->wwnn
.wwnn2
)) {
963 /* duplicate - already have vpcidev
969 (tmpvpcidev
->net
.mac_addr
, net
->mac_addr
,
970 MAX_MACADDR_LEN
) == 0) {
971 /* duplicate - already have vnic with this wwnn */
976 /* found a vhba/vnic already in the list with same
977 * wwnn or macaddr - reject add
979 write_unlock_irqrestore(&VpcidevListLock
, flags
);
981 LOGERR("**** FAILED vhba/vnic already exists in the list\n");
982 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
986 /* add it at the head */
987 if (!VpcidevListHead
)
988 VpcidevListHead
= virtpcidev
;
990 /* insert virtpcidev at the head of our linked list of
993 virtpcidev
->next
= VpcidevListHead
;
994 VpcidevListHead
= virtpcidev
;
997 write_unlock_irqrestore(&VpcidevListLock
, flags
);
999 /* Must transition channel to ATTACHED state BEFORE
1000 * registering the device, because polling of the channel
1001 * queues can begin at any time after device_register().
1003 pDev
= &virtpcidev
->generic_dev
;
1004 ULTRA_CHANNEL_CLIENT_TRANSITION(addparams
->chanptr
,
1006 CHANNELCLI_ATTACHED
, NULL
);
1008 /* don't register until device has been added to
1009 * list. Otherwise, a device_unregister from this function can
1010 * cause a "scheduling while atomic".
1012 DBGINF("registering device:%p with bus_id:%s\n",
1013 &virtpcidev
->generic_dev
, virtpcidev
->generic_dev
.bus_id
);
1014 ret
= device_register(&virtpcidev
->generic_dev
);
1015 /* NOTE: THIS IS CALLING HOTPLUG virtpci_hotplug!!!
1016 * This call to device_register results in virtpci_bus_match
1017 * being called !!!!! And, if match returns success, then
1018 * virtpcidev->generic_dev.driver is setup to core_driver,
1019 * i.e., virtpci and the probe function
1020 * virtpcidev->generic_dev.driver->probe is called which
1021 * results in virtpci_device_probe being called. And if
1022 * virtpci_device_probe is successful
1025 LOGERR("device_register returned %d\n", ret
);
1026 pDev
= &virtpcidev
->generic_dev
;
1027 ULTRA_CHANNEL_CLIENT_TRANSITION(addparams
->chanptr
,
1029 CHANNELCLI_DETACHED
, NULL
);
1030 /* remove virtpcidev, the one we just added, from the list */
1031 write_lock_irqsave(&VpcidevListLock
, flags
);
1032 for (tmpvpcidev
= VpcidevListHead
, prev
= NULL
;
1034 prev
= tmpvpcidev
, tmpvpcidev
= tmpvpcidev
->next
) {
1035 if (tmpvpcidev
== virtpcidev
) {
1037 prev
->next
= tmpvpcidev
->next
;
1039 VpcidevListHead
= tmpvpcidev
->next
;
1043 write_unlock_irqrestore(&VpcidevListLock
, flags
);
1048 LOGINF("Added %s:%d:%d &virtpcidev->generic_dev:%p\n",
1049 (devtype
== VIRTHBA_TYPE
) ? "virthba" : "virtnic",
1050 addparams
->busNo
, addparams
->deviceNo
, &virtpcidev
->generic_dev
);
1051 POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
1055 static int virtpci_device_serverdown(struct device
*parentbus
,
1057 struct vhba_wwnn
*wwnn
,
1058 unsigned char macaddr
[])
1060 int pausethisone
= 0;
1062 struct virtpci_dev
*tmpvpcidev
, *prevvpcidev
;
1063 struct virtpci_driver
*vpcidriver
;
1064 unsigned long flags
;
1067 if ((devtype
!= VIRTHBA_TYPE
) && (devtype
!= VIRTNIC_TYPE
)) {
1068 LOGERR("**** FAILED to pause device; devtype:%d not vhba:%d or vnic:%d\n",
1069 devtype
, VIRTHBA_TYPE
, VIRTNIC_TYPE
);
1073 /* find the vhba or vnic in virtpci device list */
1074 write_lock_irqsave(&VpcidevListLock
, flags
);
1076 for (tmpvpcidev
= VpcidevListHead
, prevvpcidev
= NULL
;
1077 (tmpvpcidev
&& !found
);
1078 prevvpcidev
= tmpvpcidev
, tmpvpcidev
= tmpvpcidev
->next
) {
1079 if (tmpvpcidev
->devtype
!= devtype
)
1082 if (devtype
== VIRTHBA_TYPE
) {
1084 ((tmpvpcidev
->scsi
.wwnn
.wwnn1
== wwnn
->wwnn1
) &&
1085 (tmpvpcidev
->scsi
.wwnn
.wwnn2
== wwnn
->wwnn2
));
1086 /* devtype is vhba, we're pausing vhba whose
1087 * wwnn matches the current device's wwnn
1089 } else { /* VIRTNIC_TYPE */
1091 memcmp(tmpvpcidev
->net
.mac_addr
, macaddr
,
1092 MAX_MACADDR_LEN
) == 0;
1093 /* devtype is vnic, we're pausing vnic whose
1094 * macaddr matches the current device's macaddr */
1101 vpcidriver
= tmpvpcidev
->mydriver
;
1102 rc
= vpcidriver
->suspend(tmpvpcidev
, 0);
1104 write_unlock_irqrestore(&VpcidevListLock
, flags
);
1107 LOGERR("**** FAILED to find vhba/vnic in the list\n");
1114 static int virtpci_device_serverup(struct device
*parentbus
,
1116 struct vhba_wwnn
*wwnn
,
1117 unsigned char macaddr
[])
1119 int resumethisone
= 0;
1121 struct virtpci_dev
*tmpvpcidev
, *prevvpcidev
;
1122 struct virtpci_driver
*vpcidriver
;
1123 unsigned long flags
;
1126 if ((devtype
!= VIRTHBA_TYPE
) && (devtype
!= VIRTNIC_TYPE
)) {
1127 LOGERR("**** FAILED to resume device; devtype:%d not vhba:%d or vnic:%d\n",
1128 devtype
, VIRTHBA_TYPE
, VIRTNIC_TYPE
);
1132 /* find the vhba or vnic in virtpci device list */
1133 write_lock_irqsave(&VpcidevListLock
, flags
);
1135 for (tmpvpcidev
= VpcidevListHead
, prevvpcidev
= NULL
;
1136 (tmpvpcidev
&& !found
);
1137 prevvpcidev
= tmpvpcidev
, tmpvpcidev
= tmpvpcidev
->next
) {
1138 if (tmpvpcidev
->devtype
!= devtype
)
1141 if (devtype
== VIRTHBA_TYPE
) {
1143 ((tmpvpcidev
->scsi
.wwnn
.wwnn1
== wwnn
->wwnn1
) &&
1144 (tmpvpcidev
->scsi
.wwnn
.wwnn2
== wwnn
->wwnn2
));
1145 /* devtype is vhba, we're resuming vhba whose
1146 * wwnn matches the current device's wwnn */
1147 } else { /* VIRTNIC_TYPE */
1149 memcmp(tmpvpcidev
->net
.mac_addr
, macaddr
,
1150 MAX_MACADDR_LEN
) == 0;
1151 /* devtype is vnic, we're resuming vnic whose
1152 * macaddr matches the current device's macaddr */
1159 vpcidriver
= tmpvpcidev
->mydriver
;
1160 /* This should be done at BUS resume time, but an
1161 * existing problem prevents us from ever getting a bus
1162 * resume... This hack would fail to work should we
1163 * ever have a bus that contains NO devices, since we
1164 * would never even get here in that case.
1166 fix_vbus_devInfo(&tmpvpcidev
->generic_dev
, tmpvpcidev
->deviceNo
,
1167 tmpvpcidev
->device
, vpcidriver
);
1168 rc
= vpcidriver
->resume(tmpvpcidev
);
1171 write_unlock_irqrestore(&VpcidevListLock
, flags
);
1174 LOGERR("**** FAILED to find vhba/vnic in the list\n");
1181 static int virtpci_device_del(struct device
*parentbus
,
1182 int devtype
, struct vhba_wwnn
*wwnn
,
1183 unsigned char macaddr
[])
1185 int count
= 0, all
= 0, delthisone
;
1186 struct virtpci_dev
*tmpvpcidev
, *prevvpcidev
, *dellist
= NULL
;
1187 unsigned long flags
;
1189 #define DEL_CONTINUE { \
1190 prevvpcidev = tmpvpcidev;\
1191 tmpvpcidev = tmpvpcidev->next;\
1195 if ((devtype
!= VIRTHBA_TYPE
) && (devtype
!= VIRTNIC_TYPE
)) {
1196 LOGERR("**** FAILED to delete device; devtype:%d not vhba:%d or vnic:%d\n",
1197 devtype
, VIRTHBA_TYPE
, VIRTNIC_TYPE
);
1201 /* see if we are to delete all - NOTE: all implies we have a
1204 all
= ((devtype
== VIRTHBA_TYPE
) && (wwnn
== NULL
)) ||
1205 ((devtype
== VIRTNIC_TYPE
) && (macaddr
== NULL
));
1207 /* find all the vhba or vnic or both in virtpci device list
1208 * keep list of ones we are deleting so we can call
1209 * device_unregister after we release the lock; otherwise we
1210 * encounter "schedule while atomic"
1212 write_lock_irqsave(&VpcidevListLock
, flags
);
1213 for (tmpvpcidev
= VpcidevListHead
, prevvpcidev
= NULL
; tmpvpcidev
;) {
1214 if (tmpvpcidev
->devtype
!= devtype
)
1219 (tmpvpcidev
->generic_dev
.parent
== parentbus
);
1220 /* we're deleting all vhbas or vnics on the
1221 * specified parent bus
1223 } else if (devtype
== VIRTHBA_TYPE
) {
1225 ((tmpvpcidev
->scsi
.wwnn
.wwnn1
== wwnn
->wwnn1
) &&
1226 (tmpvpcidev
->scsi
.wwnn
.wwnn2
== wwnn
->wwnn2
));
1227 /* devtype is vhba, we're deleting vhba whose
1228 * wwnn matches the current device's wwnn
1230 } else { /* VIRTNIC_TYPE */
1232 memcmp(tmpvpcidev
->net
.mac_addr
, macaddr
,
1233 MAX_MACADDR_LEN
) == 0;
1234 /* devtype is vnic, we're deleting vnic whose
1235 * macaddr matches the current device's macaddr
1242 /* take vhba/vnic out of the list */
1245 prevvpcidev
->next
= tmpvpcidev
->next
;
1247 VpcidevListHead
= tmpvpcidev
->next
;
1249 /* add it to our deletelist */
1250 tmpvpcidev
->next
= dellist
;
1251 dellist
= tmpvpcidev
;
1256 /* going to top of loop again - set tmpvpcidev to next
1257 * one we're to process
1260 tmpvpcidev
= prevvpcidev
->next
;
1262 tmpvpcidev
= VpcidevListHead
;
1264 write_unlock_irqrestore(&VpcidevListLock
, flags
);
1266 if (!all
&& (count
== 0)) {
1267 LOGERR("**** FAILED to find vhba/vnic in the list\n");
1271 /* now delete each one from delete list */
1274 tmpvpcidev
= dellist
->next
;
1275 /* delete the vhba/vnic at dellist */
1276 DELETE_ONE_VPCIDEV(dellist
);
1278 dellist
= tmpvpcidev
;
1284 static void virtpci_device_release(struct device
*dev_
)
1286 /* this function is called when the last reference to the
1289 LOGINF("In virtpci_device_release:%p - NOT YET IMPLEMENTED\n", dev_
);
1292 /*****************************************************/
1293 /* Driver functions */
1294 /*****************************************************/
1296 #define kobj_to_device_driver(obj) container_of(obj, struct device_driver, kobj)
1297 #define attribute_to_driver_attribute(obj) \
1298 container_of(obj, struct driver_attribute, attr)
1300 static ssize_t
virtpci_driver_attr_show(struct kobject
*kobj
,
1301 struct attribute
*attr
,
1304 struct driver_attribute
*dattr
= attribute_to_driver_attribute(attr
);
1307 struct driver_private
*dprivate
= to_driver(kobj
);
1308 struct device_driver
*driver
;
1309 if (dprivate
!= NULL
)
1310 driver
= dprivate
->driver
;
1314 DBGINF("In virtpci_driver_attr_show driver->name:%s\n", driver
->name
);
1317 ret
= dattr
->show(driver
, buf
);
1322 static ssize_t
virtpci_driver_attr_store(struct kobject
*kobj
,
1323 struct attribute
*attr
,
1324 const char *buf
, size_t count
)
1326 struct driver_attribute
*dattr
= attribute_to_driver_attribute(attr
);
1329 struct driver_private
*dprivate
= to_driver(kobj
);
1330 struct device_driver
*driver
;
1331 if (dprivate
!= NULL
)
1332 driver
= dprivate
->driver
;
1336 DBGINF("In virtpci_driver_attr_store driver->name:%s\n", driver
->name
);
1340 ret
= dattr
->store(driver
, buf
, count
);
1345 /* register a new virtpci driver */
1346 int virtpci_register_driver(struct virtpci_driver
*drv
)
1350 DBGINF("In virtpci_register_driver\n");
1352 if (drv
->id_table
== NULL
) {
1353 LOGERR("id_table missing\n");
1356 /* initialize core driver fields needed to call driver_register */
1357 drv
->core_driver
.name
= drv
->name
; /* name of driver in sysfs */
1358 drv
->core_driver
.bus
= &virtpci_bus_type
; /* type of bus this
1359 * driver works with */
1360 drv
->core_driver
.probe
= virtpci_device_probe
; /* called to query the
1362 * specific device and
1363 * whether this driver
1364 *can work with it */
1365 drv
->core_driver
.remove
= virtpci_device_remove
; /* called when the
1367 * from the system */
1368 /* register with core */
1369 result
= driver_register(&drv
->core_driver
);
1370 /* calls bus_add_driver which calls driver_attach and
1374 return result
; /* failed */
1376 drv
->core_driver
.p
->kobj
.ktype
= &virtpci_driver_kobj_type
;
1380 EXPORT_SYMBOL_GPL(virtpci_register_driver
);
1382 void virtpci_unregister_driver(struct virtpci_driver
*drv
)
1384 DBGINF("In virtpci_unregister_driver drv:%p\n", drv
);
1385 driver_unregister(&drv
->core_driver
);
1386 /* driver_unregister calls bus_remove_driver
1387 * bus_remove_driver calls device_detach
1388 * device_detach calls device_release_driver for each of the
1390 * device_release driver calls drv->remove which is
1391 * virtpci_device_remove
1392 * virtpci_device_remove calls virthba_remove
1394 DBGINF("Leaving\n");
1396 EXPORT_SYMBOL_GPL(virtpci_unregister_driver
);
1398 /*****************************************************/
1399 /* debugfs filesystem functions */
1400 /*****************************************************/
1401 struct print_vbus_info
{
1407 static int print_vbus(struct device
*vbus
, void *data
)
1409 struct print_vbus_info
*p
= (struct print_vbus_info
*)data
;
1411 *p
->str_pos
+= scnprintf(p
->buf
+ *p
->str_pos
, *p
->len
- *p
->str_pos
,
1412 "bus_id:%s\n", dev_name(vbus
));
1416 static ssize_t
info_debugfs_read(struct file
*file
, char __user
*buf
,
1417 size_t len
, loff_t
*offset
)
1419 ssize_t bytes_read
= 0;
1421 struct virtpci_dev
*tmpvpcidev
;
1422 unsigned long flags
;
1423 struct print_vbus_info printparam
;
1428 vbuf
= kzalloc(len
, GFP_KERNEL
);
1432 str_pos
+= scnprintf(vbuf
+ str_pos
, len
- str_pos
,
1433 " Virtual PCI Bus devices\n");
1434 printparam
.str_pos
= &str_pos
;
1435 printparam
.buf
= vbuf
;
1436 printparam
.len
= &len
;
1437 if (bus_for_each_dev(&virtpci_bus_type
, NULL
,
1438 (void *) &printparam
, print_vbus
))
1439 LOGERR("Failed to find bus\n");
1441 str_pos
+= scnprintf(vbuf
+ str_pos
, len
- str_pos
,
1442 "\n Virtual PCI devices\n");
1443 read_lock_irqsave(&VpcidevListLock
, flags
);
1444 tmpvpcidev
= VpcidevListHead
;
1445 while (tmpvpcidev
) {
1446 if (tmpvpcidev
->devtype
== VIRTHBA_TYPE
) {
1447 str_pos
+= scnprintf(vbuf
+ str_pos
, len
- str_pos
,
1448 "[%d:%d] VHba:%08x:%08x max-config:%d-%d-%d-%d",
1449 tmpvpcidev
->busNo
, tmpvpcidev
->deviceNo
,
1450 tmpvpcidev
->scsi
.wwnn
.wwnn1
,
1451 tmpvpcidev
->scsi
.wwnn
.wwnn2
,
1452 tmpvpcidev
->scsi
.max
.max_channel
,
1453 tmpvpcidev
->scsi
.max
.max_id
,
1454 tmpvpcidev
->scsi
.max
.max_lun
,
1455 tmpvpcidev
->scsi
.max
.cmd_per_lun
);
1457 str_pos
+= scnprintf(vbuf
+ str_pos
, len
- str_pos
,
1458 "[%d:%d] VNic:%02x:%02x:%02x:%02x:%02x:%02x num_rcv_bufs:%d mtu:%d",
1459 tmpvpcidev
->busNo
, tmpvpcidev
->deviceNo
,
1460 tmpvpcidev
->net
.mac_addr
[0],
1461 tmpvpcidev
->net
.mac_addr
[1],
1462 tmpvpcidev
->net
.mac_addr
[2],
1463 tmpvpcidev
->net
.mac_addr
[3],
1464 tmpvpcidev
->net
.mac_addr
[4],
1465 tmpvpcidev
->net
.mac_addr
[5],
1466 tmpvpcidev
->net
.num_rcv_bufs
,
1467 tmpvpcidev
->net
.mtu
);
1469 str_pos
+= scnprintf(vbuf
+ str_pos
,
1470 len
- str_pos
, " chanptr:%p\n",
1471 tmpvpcidev
->queueinfo
.chan
);
1472 tmpvpcidev
= tmpvpcidev
->next
;
1474 read_unlock_irqrestore(&VpcidevListLock
, flags
);
1476 str_pos
+= scnprintf(vbuf
+ str_pos
, len
- str_pos
, "\n");
1477 bytes_read
= simple_read_from_buffer(buf
, len
, offset
, vbuf
, str_pos
);
1482 /*****************************************************/
1483 /* Module Init & Exit functions */
1484 /*****************************************************/
1486 static int __init
virtpci_mod_init(void)
1491 if (!unisys_spar_platform
)
1494 POSTCODE_LINUX_2(VPCI_CREATE_ENTRY_PC
, POSTCODE_SEVERITY_INFO
);
1496 ret
= bus_register(&virtpci_bus_type
);
1497 /* creates /sys/bus/uisvirtpci which contains devices &
1501 LOGERR("bus_register ****FAILED:%d\n", ret
);
1502 POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC
, ret
,
1503 POSTCODE_SEVERITY_ERR
);
1506 DBGINF("bus_register successful\n");
1507 BusDeviceInfo_Init(&Bus_DriverInfo
, "clientbus", "virtpci",
1510 /* create a root bus used to parent all the virtpci buses. */
1511 ret
= device_register(&virtpci_rootbus_device
);
1513 LOGERR("device_register FAILED:%d\n", ret
);
1514 bus_unregister(&virtpci_bus_type
);
1515 POSTCODE_LINUX_3(VPCI_CREATE_FAILURE_PC
, ret
,
1516 POSTCODE_SEVERITY_ERR
);
1519 DBGINF("device_register successful ret:%x\n", ret
);
1521 if (!uisctrl_register_req_handler(2, (void *) &virtpci_ctrlchan_func
,
1522 &Chipset_DriverInfo
)) {
1523 LOGERR("uisctrl_register_req_handler ****FAILED.\n");
1524 POSTCODE_LINUX_2(VPCI_CREATE_FAILURE_PC
, POSTCODE_SEVERITY_ERR
);
1525 device_unregister(&virtpci_rootbus_device
);
1526 bus_unregister(&virtpci_bus_type
);
1530 LOGINF("successfully registered virtpci_ctrlchan_func (0x%p) as callback.\n",
1531 (void *) &virtpci_ctrlchan_func
);
1532 /* create debugfs directory and info file inside. */
1533 virtpci_debugfs_dir
= debugfs_create_dir("virtpci", NULL
);
1534 debugfs_create_file("info", S_IRUSR
, virtpci_debugfs_dir
,
1535 NULL
, &debugfs_info_fops
);
1536 LOGINF("Leaving\n");
1537 POSTCODE_LINUX_2(VPCI_CREATE_EXIT_PC
, POSTCODE_SEVERITY_INFO
);
1541 static void __exit
virtpci_mod_exit(void)
1543 LOGINF("virtpci_mod_exit...\n");
1545 /* unregister the callback function */
1546 if (!uisctrl_register_req_handler(2, NULL
, NULL
))
1547 LOGERR("uisctrl_register_req_handler ****FAILED.\n");
1549 device_unregister(&virtpci_rootbus_device
);
1550 bus_unregister(&virtpci_bus_type
);
1551 debugfs_remove_recursive(virtpci_debugfs_dir
);
1552 LOGINF("Leaving\n");
1556 module_init(virtpci_mod_init
);
1557 module_exit(virtpci_mod_exit
);
1558 MODULE_LICENSE("GPL");
1559 MODULE_AUTHOR("Usha Srinivasan");
1560 MODULE_ALIAS("uisvirtpci");