@@ -351,7 +351,10 @@ struct storvsc_cmd_request {
351
351
/* Synchronize the request/response if needed */
352
352
struct completion wait_event ;
353
353
354
- struct hv_multipage_buffer data_buffer ;
354
+ struct vmbus_channel_packet_multipage_buffer mpb ;
355
+ struct vmbus_packet_mpb_array * payload ;
356
+ u32 payload_sz ;
357
+
355
358
struct vstor_packet vstor_packet ;
356
359
};
357
360
@@ -1103,6 +1106,8 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
1103
1106
struct Scsi_Host * host ;
1104
1107
struct storvsc_device * stor_dev ;
1105
1108
struct hv_device * dev = host_dev -> dev ;
1109
+ u32 payload_sz = cmd_request -> payload_sz ;
1110
+ void * payload = cmd_request -> payload ;
1106
1111
1107
1112
stor_dev = get_in_stor_device (dev );
1108
1113
host = stor_dev -> host ;
@@ -1132,10 +1137,14 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request)
1132
1137
sense_hdr .ascq );
1133
1138
1134
1139
scsi_set_resid (scmnd ,
1135
- cmd_request -> data_buffer .len -
1140
+ cmd_request -> payload -> range .len -
1136
1141
vm_srb -> data_transfer_length );
1137
1142
1138
1143
scmnd -> scsi_done (scmnd );
1144
+
1145
+ if (payload_sz >
1146
+ sizeof (struct vmbus_channel_packet_multipage_buffer ))
1147
+ kfree (payload );
1139
1148
}
1140
1149
1141
1150
static void storvsc_on_io_completion (struct hv_device * device ,
@@ -1337,7 +1346,7 @@ static int storvsc_dev_remove(struct hv_device *device)
1337
1346
}
1338
1347
1339
1348
static int storvsc_do_io (struct hv_device * device ,
1340
- struct storvsc_cmd_request * request )
1349
+ struct storvsc_cmd_request * request )
1341
1350
{
1342
1351
struct storvsc_device * stor_device ;
1343
1352
struct vstor_packet * vstor_packet ;
@@ -1369,13 +1378,14 @@ static int storvsc_do_io(struct hv_device *device,
1369
1378
1370
1379
1371
1380
vstor_packet -> vm_srb .data_transfer_length =
1372
- request -> data_buffer .len ;
1381
+ request -> payload -> range .len ;
1373
1382
1374
1383
vstor_packet -> operation = VSTOR_OPERATION_EXECUTE_SRB ;
1375
1384
1376
- if (request -> data_buffer .len ) {
1377
- ret = vmbus_sendpacket_multipagebuffer (outgoing_channel ,
1378
- & request -> data_buffer ,
1385
+ if (request -> payload -> range .len ) {
1386
+
1387
+ ret = vmbus_sendpacket_mpb_desc (outgoing_channel ,
1388
+ request -> payload , request -> payload_sz ,
1379
1389
vstor_packet ,
1380
1390
(sizeof (struct vstor_packet ) -
1381
1391
vmscsi_size_delta ),
@@ -1549,6 +1559,9 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
1549
1559
unsigned int sg_count = 0 ;
1550
1560
struct vmscsi_request * vm_srb ;
1551
1561
struct scatterlist * cur_sgl ;
1562
+ struct vmbus_packet_mpb_array * payload ;
1563
+ u32 payload_sz ;
1564
+ u32 length ;
1552
1565
1553
1566
if (vmstor_current_major <= VMSTOR_WIN8_MAJOR ) {
1554
1567
/*
@@ -1602,48 +1615,71 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd)
1602
1615
1603
1616
memcpy (vm_srb -> cdb , scmnd -> cmnd , vm_srb -> cdb_length );
1604
1617
1605
- cmd_request -> data_buffer .len = scsi_bufflen (scmnd );
1606
- if (scsi_sg_count (scmnd )) {
1607
- sgl = (struct scatterlist * )scsi_sglist (scmnd );
1608
- sg_count = scsi_sg_count (scmnd );
1618
+ sgl = (struct scatterlist * )scsi_sglist (scmnd );
1619
+ sg_count = scsi_sg_count (scmnd );
1609
1620
1621
+ length = scsi_bufflen (scmnd );
1622
+ payload = (struct vmbus_packet_mpb_array * )& cmd_request -> mpb ;
1623
+ payload_sz = sizeof (cmd_request -> mpb );
1624
+
1625
+ if (sg_count ) {
1610
1626
/* check if we need to bounce the sgl */
1611
1627
if (do_bounce_buffer (sgl , scsi_sg_count (scmnd )) != -1 ) {
1612
1628
cmd_request -> bounce_sgl =
1613
- create_bounce_buffer (sgl , scsi_sg_count ( scmnd ) ,
1614
- scsi_bufflen ( scmnd ) ,
1629
+ create_bounce_buffer (sgl , sg_count ,
1630
+ length ,
1615
1631
vm_srb -> data_in );
1616
1632
if (!cmd_request -> bounce_sgl )
1617
1633
return SCSI_MLQUEUE_HOST_BUSY ;
1618
1634
1619
1635
cmd_request -> bounce_sgl_count =
1620
- ALIGN (scsi_bufflen (scmnd ), PAGE_SIZE ) >>
1621
- PAGE_SHIFT ;
1636
+ ALIGN (length , PAGE_SIZE ) >> PAGE_SHIFT ;
1622
1637
1623
1638
if (vm_srb -> data_in == WRITE_TYPE )
1624
1639
copy_to_bounce_buffer (sgl ,
1625
- cmd_request -> bounce_sgl ,
1626
- scsi_sg_count (scmnd ));
1640
+ cmd_request -> bounce_sgl , sg_count );
1627
1641
1628
1642
sgl = cmd_request -> bounce_sgl ;
1629
1643
sg_count = cmd_request -> bounce_sgl_count ;
1630
1644
}
1631
1645
1632
- cmd_request -> data_buffer .offset = sgl [0 ].offset ;
1646
+
1647
+ if (sg_count > MAX_PAGE_BUFFER_COUNT ) {
1648
+
1649
+ payload_sz = (sg_count * sizeof (void * ) +
1650
+ sizeof (struct vmbus_packet_mpb_array ));
1651
+ payload = kmalloc (payload_sz , GFP_ATOMIC );
1652
+ if (!payload ) {
1653
+ if (cmd_request -> bounce_sgl_count )
1654
+ destroy_bounce_buffer (
1655
+ cmd_request -> bounce_sgl ,
1656
+ cmd_request -> bounce_sgl_count );
1657
+
1658
+ return SCSI_MLQUEUE_DEVICE_BUSY ;
1659
+ }
1660
+ }
1661
+
1662
+ payload -> range .len = length ;
1663
+ payload -> range .offset = sgl [0 ].offset ;
1664
+
1633
1665
cur_sgl = sgl ;
1634
1666
for (i = 0 ; i < sg_count ; i ++ ) {
1635
- cmd_request -> data_buffer .pfn_array [i ] =
1667
+ payload -> range .pfn_array [i ] =
1636
1668
page_to_pfn (sg_page ((cur_sgl )));
1637
1669
cur_sgl = sg_next (cur_sgl );
1638
1670
}
1639
1671
1640
1672
} else if (scsi_sglist (scmnd )) {
1641
- cmd_request -> data_buffer .offset =
1673
+ payload -> range .len = length ;
1674
+ payload -> range .offset =
1642
1675
virt_to_phys (scsi_sglist (scmnd )) & (PAGE_SIZE - 1 );
1643
- cmd_request -> data_buffer .pfn_array [0 ] =
1676
+ payload -> range .pfn_array [0 ] =
1644
1677
virt_to_phys (scsi_sglist (scmnd )) >> PAGE_SHIFT ;
1645
1678
}
1646
1679
1680
+ cmd_request -> payload = payload ;
1681
+ cmd_request -> payload_sz = payload_sz ;
1682
+
1647
1683
/* Invokes the vsc to start an IO */
1648
1684
ret = storvsc_do_io (dev , cmd_request );
1649
1685
@@ -1672,10 +1708,7 @@ static struct scsi_host_template scsi_driver = {
1672
1708
.slave_configure = storvsc_device_configure ,
1673
1709
.cmd_per_lun = 255 ,
1674
1710
.this_id = -1 ,
1675
- /* no use setting to 0 since ll_blk_rw reset it to 1 */
1676
- /* currently 32 */
1677
- .sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT ,
1678
- .use_clustering = DISABLE_CLUSTERING ,
1711
+ .use_clustering = ENABLE_CLUSTERING ,
1679
1712
/* Make sure we dont get a sg segment crosses a page boundary */
1680
1713
.dma_boundary = PAGE_SIZE - 1 ,
1681
1714
.no_write_same = 1 ,
@@ -1812,6 +1845,12 @@ static int storvsc_probe(struct hv_device *device,
1812
1845
/* max cmd length */
1813
1846
host -> max_cmd_len = STORVSC_MAX_CMD_LEN ;
1814
1847
1848
+ /*
1849
+ * set the table size based on the info we got
1850
+ * from the host.
1851
+ */
1852
+ host -> sg_tablesize = (stor_device -> max_transfer_bytes >> PAGE_SHIFT );
1853
+
1815
1854
/* Register the HBA and start the scsi bus scan */
1816
1855
ret = scsi_add_host (host , & device -> device );
1817
1856
if (ret != 0 )
0 commit comments