70
70
#include <linux/moduleparam.h>
71
71
#include <linux/dma-mapping.h>
72
72
#include <linux/delay.h>
73
+ #include <asm/firmware.h>
73
74
#include <asm/vio.h>
74
75
#include <scsi/scsi.h>
75
76
#include <scsi/scsi_cmnd.h>
@@ -92,6 +93,8 @@ static struct scsi_transport_template *ibmvscsi_transport_template;
92
93
93
94
#define IBMVSCSI_VERSION "1.5.8"
94
95
96
+ static struct ibmvscsi_ops * ibmvscsi_ops ;
97
+
95
98
MODULE_DESCRIPTION ("IBM Virtual SCSI" );
96
99
MODULE_AUTHOR ("Dave Boutcher" );
97
100
MODULE_LICENSE ("GPL" );
@@ -509,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata)
509
512
atomic_set (& hostdata -> request_limit , 0 );
510
513
511
514
purge_requests (hostdata , DID_ERROR );
512
- if ((ibmvscsi_reset_crq_queue (& hostdata -> queue , hostdata )) ||
513
- (ibmvscsi_send_crq (hostdata , 0xC001000000000000LL , 0 )) ||
515
+ if ((ibmvscsi_ops -> reset_crq_queue (& hostdata -> queue , hostdata )) ||
516
+ (ibmvscsi_ops -> send_crq (hostdata , 0xC001000000000000LL , 0 )) ||
514
517
(vio_enable_interrupts (to_vio_dev (hostdata -> dev )))) {
515
518
atomic_set (& hostdata -> request_limit , -1 );
516
519
dev_err (hostdata -> dev , "error after reset\n" );
@@ -615,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct,
615
618
}
616
619
617
620
if ((rc =
618
- ibmvscsi_send_crq (hostdata , crq_as_u64 [0 ], crq_as_u64 [1 ])) != 0 ) {
621
+ ibmvscsi_ops -> send_crq (hostdata , crq_as_u64 [0 ], crq_as_u64 [1 ])) != 0 ) {
619
622
list_del (& evt_struct -> list );
620
623
del_timer (& evt_struct -> timer );
621
624
@@ -1214,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1214
1217
case 0x01 : /* Initialization message */
1215
1218
dev_info (hostdata -> dev , "partner initialized\n" );
1216
1219
/* Send back a response */
1217
- if ((rc = ibmvscsi_send_crq (hostdata ,
1218
- 0xC002000000000000LL , 0 )) == 0 ) {
1220
+ if ((rc = ibmvscsi_ops -> send_crq (hostdata ,
1221
+ 0xC002000000000000LL , 0 )) == 0 ) {
1219
1222
/* Now login */
1220
1223
send_srp_login (hostdata );
1221
1224
} else {
@@ -1240,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1240
1243
/* We need to re-setup the interpartition connection */
1241
1244
dev_info (hostdata -> dev , "Re-enabling adapter!\n" );
1242
1245
purge_requests (hostdata , DID_REQUEUE );
1243
- if ((ibmvscsi_reenable_crq_queue (& hostdata -> queue ,
1244
- hostdata )) ||
1245
- (ibmvscsi_send_crq (hostdata ,
1246
- 0xC001000000000000LL , 0 ))) {
1246
+ if ((ibmvscsi_ops -> reenable_crq_queue (& hostdata -> queue ,
1247
+ hostdata )) ||
1248
+ (ibmvscsi_ops -> send_crq (hostdata ,
1249
+ 0xC001000000000000LL , 0 ))) {
1247
1250
atomic_set (& hostdata -> request_limit ,
1248
1251
-1 );
1249
1252
dev_err (hostdata -> dev , "error after enable\n" );
@@ -1253,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq,
1253
1256
crq -> format );
1254
1257
1255
1258
purge_requests (hostdata , DID_ERROR );
1256
- if ((ibmvscsi_reset_crq_queue (& hostdata -> queue ,
1257
- hostdata )) ||
1258
- (ibmvscsi_send_crq (hostdata ,
1259
- 0xC001000000000000LL , 0 ))) {
1259
+ if ((ibmvscsi_ops -> reset_crq_queue (& hostdata -> queue ,
1260
+ hostdata )) ||
1261
+ (ibmvscsi_ops -> send_crq (hostdata ,
1262
+ 0xC001000000000000LL , 0 ))) {
1260
1263
atomic_set (& hostdata -> request_limit ,
1261
1264
-1 );
1262
1265
dev_err (hostdata -> dev , "error after reset\n" );
@@ -1579,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1579
1582
atomic_set (& hostdata -> request_limit , -1 );
1580
1583
hostdata -> host -> max_sectors = 32 * 8 ; /* default max I/O 32 pages */
1581
1584
1582
- rc = ibmvscsi_init_crq_queue (& hostdata -> queue , hostdata , max_requests );
1585
+ rc = ibmvscsi_ops -> init_crq_queue (& hostdata -> queue , hostdata , max_requests );
1583
1586
if (rc != 0 && rc != H_RESOURCE ) {
1584
1587
dev_err (& vdev -> dev , "couldn't initialize crq. rc=%d\n" , rc );
1585
1588
goto init_crq_failed ;
@@ -1608,7 +1611,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1608
1611
* to fail if the other end is not acive. In that case we don't
1609
1612
* want to scan
1610
1613
*/
1611
- if (ibmvscsi_send_crq (hostdata , 0xC001000000000000LL , 0 ) == 0
1614
+ if (ibmvscsi_ops -> send_crq (hostdata , 0xC001000000000000LL , 0 ) == 0
1612
1615
|| rc == H_RESOURCE ) {
1613
1616
/*
1614
1617
* Wait around max init_timeout secs for the adapter to finish
@@ -1636,7 +1639,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id)
1636
1639
add_host_failed :
1637
1640
release_event_pool (& hostdata -> pool , hostdata );
1638
1641
init_pool_failed :
1639
- ibmvscsi_release_crq_queue (& hostdata -> queue , hostdata , max_requests );
1642
+ ibmvscsi_ops -> release_crq_queue (& hostdata -> queue , hostdata , max_requests );
1640
1643
init_crq_failed :
1641
1644
scsi_host_put (host );
1642
1645
scsi_host_alloc_failed :
@@ -1647,8 +1650,8 @@ static int ibmvscsi_remove(struct vio_dev *vdev)
1647
1650
{
1648
1651
struct ibmvscsi_host_data * hostdata = vdev -> dev .driver_data ;
1649
1652
release_event_pool (& hostdata -> pool , hostdata );
1650
- ibmvscsi_release_crq_queue (& hostdata -> queue , hostdata ,
1651
- max_requests );
1653
+ ibmvscsi_ops -> release_crq_queue (& hostdata -> queue , hostdata ,
1654
+ max_requests );
1652
1655
1653
1656
srp_remove_host (hostdata -> host );
1654
1657
scsi_remove_host (hostdata -> host );
@@ -1684,6 +1687,13 @@ int __init ibmvscsi_module_init(void)
1684
1687
{
1685
1688
int ret ;
1686
1689
1690
+ if (firmware_has_feature (FW_FEATURE_ISERIES ))
1691
+ ibmvscsi_ops = & iseriesvscsi_ops ;
1692
+ else if (firmware_has_feature (FW_FEATURE_VIO ))
1693
+ ibmvscsi_ops = & rpavscsi_ops ;
1694
+ else
1695
+ return - ENODEV ;
1696
+
1687
1697
ibmvscsi_transport_template =
1688
1698
srp_attach_transport (& ibmvscsi_transport_functions );
1689
1699
if (!ibmvscsi_transport_template )
0 commit comments