Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hptiop: Support HighPoint RR36xx HBAs and Support SAS tape and SAS media changer

Support HighPoint RR36xx HBAs which are based on Marvell Frey.
Support SAS tape and SAS media changer.

[jejb: remove now unused label]
Signed-off-by: HighPoint Linux Team <linux@highpoint-tech.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>

authored by

linux and committed by
James Bottomley
a93429c3 442d7562

+67 -40
+64 -37
drivers/scsi/hptiop.c
··· 1 1 /* 2 2 * HighPoint RR3xxx/4xxx controller driver for Linux 3 - * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved. 3 + * Copyright (C) 2006-2015 HighPoint Technologies, Inc. All Rights Reserved. 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify 6 6 * it under the terms of the GNU General Public License as published by ··· 42 42 43 43 static char driver_name[] = "hptiop"; 44 44 static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller driver"; 45 - static const char driver_ver[] = "v1.8"; 45 + static const char driver_ver[] = "v1.10.0"; 46 46 47 47 static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec); 48 48 static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag, ··· 764 764 scsi_set_resid(scp, 765 765 scsi_bufflen(scp) - le32_to_cpu(req->dataxfer_length)); 766 766 scp->result = SAM_STAT_CHECK_CONDITION; 767 - memcpy(scp->sense_buffer, &req->sg_list, 768 - min_t(size_t, SCSI_SENSE_BUFFERSIZE, 769 - le32_to_cpu(req->dataxfer_length))); 767 + memcpy(scp->sense_buffer, &req->sg_list, SCSI_SENSE_BUFFERSIZE); 770 768 goto skip_resid; 771 769 break; 772 770 ··· 1035 1037 1036 1038 scp->result = 0; 1037 1039 1038 - if (scp->device->channel || scp->device->lun || 1039 - scp->device->id > hba->max_devices) { 1040 + if (scp->device->channel || 1041 + (scp->device->id > hba->max_devices) || 1042 + ((scp->device->id == (hba->max_devices-1)) && scp->device->lun)) { 1040 1043 scp->result = DID_BAD_TARGET << 16; 1041 1044 free_req(hba, _req); 1042 1045 goto cmd_done; ··· 1167 1168 NULL 1168 1169 }; 1169 1170 1171 + static int hptiop_slave_config(struct scsi_device *sdev) 1172 + { 1173 + if (sdev->type == TYPE_TAPE) 1174 + blk_queue_max_hw_sectors(sdev->request_queue, 8192); 1175 + 1176 + return 0; 1177 + } 1178 + 1170 1179 static struct scsi_host_template driver_template = { 1171 1180 .module = THIS_MODULE, 1172 1181 .name = driver_name, ··· 1186 1179 .use_clustering = ENABLE_CLUSTERING, 1187 1180 .proc_name = driver_name, 1188 1181 .shost_attrs = hptiop_attrs, 1182 + .slave_configure = hptiop_slave_config, 1189 1183 .this_id = -1, 1190 1184 .change_queue_depth = hptiop_adjust_disk_queue_depth, 1191 1185 }; ··· 1331 1323 } 1332 1324 1333 1325 hba = (struct hptiop_hba *)host->hostdata; 1326 + memset(hba, 0, sizeof(struct hptiop_hba)); 1334 1327 1335 1328 hba->ops = iop_ops; 1336 1329 hba->pcidev = pcidev; ··· 1345 1336 init_waitqueue_head(&hba->reset_wq); 1346 1337 init_waitqueue_head(&hba->ioctl_wq); 1347 1338 1348 - host->max_lun = 1; 1339 + host->max_lun = 128; 1349 1340 host->max_channel = 0; 1350 1341 host->io_port = 0; 1351 1342 host->n_io_port = 0; ··· 1437 1428 dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); 1438 1429 1439 1430 hba->req_size = req_size; 1440 - start_virt = dma_alloc_coherent(&pcidev->dev, 1441 - hba->req_size*hba->max_requests + 0x20, 1442 - &start_phy, GFP_KERNEL); 1443 - 1444 - if (!start_virt) { 1445 - printk(KERN_ERR "scsi%d: fail to alloc request mem\n", 1446 - hba->host->host_no); 1447 - goto free_request_irq; 1448 - } 1449 - 1450 - hba->dma_coherent = start_virt; 1451 - hba->dma_coherent_handle = start_phy; 1452 - 1453 - if ((start_phy & 0x1f) != 0) { 1454 - offset = ((start_phy + 0x1f) & ~0x1f) - start_phy; 1455 - start_phy += offset; 1456 - start_virt += offset; 1457 - } 1458 - 1459 1431 hba->req_list = NULL; 1432 + 1460 1433 for (i = 0; i < hba->max_requests; i++) { 1434 + start_virt = dma_alloc_coherent(&pcidev->dev, 1435 + hba->req_size + 0x20, 1436 + &start_phy, GFP_KERNEL); 1437 + 1438 + if (!start_virt) { 1439 + printk(KERN_ERR "scsi%d: fail to alloc request mem\n", 1440 + hba->host->host_no); 1441 + goto free_request_mem; 1442 + } 1443 + 1444 + hba->dma_coherent[i] = start_virt; 1445 + hba->dma_coherent_handle[i] = start_phy; 1446 + 1447 + if ((start_phy & 0x1f) != 0) { 1448 + offset = ((start_phy + 0x1f) & ~0x1f) - start_phy; 1449 + start_phy += offset; 1450 + start_virt += offset; 1451 + } 1452 + 1461 1453 hba->reqs[i].next = NULL; 1462 1454 hba->reqs[i].req_virt = start_virt; 1463 1455 hba->reqs[i].req_shifted_phy = start_phy >> 5; 1464 1456 hba->reqs[i].index = i; 1465 1457 free_req(hba, &hba->reqs[i]); 1466 - start_virt = (char *)start_virt + hba->req_size; 1467 - start_phy = start_phy + hba->req_size; 1468 1458 } 1469 1459 1470 1460 /* Enable Interrupt and start background task */ ··· 1482 1474 return 0; 1483 1475 1484 1476 free_request_mem: 1485 - dma_free_coherent(&hba->pcidev->dev, 1486 - hba->req_size * hba->max_requests + 0x20, 1487 - hba->dma_coherent, hba->dma_coherent_handle); 1477 + for (i = 0; i < hba->max_requests; i++) { 1478 + if (hba->dma_coherent[i] && hba->dma_coherent_handle[i]) 1479 + dma_free_coherent(&hba->pcidev->dev, 1480 + hba->req_size + 0x20, 1481 + hba->dma_coherent[i], 1482 + hba->dma_coherent_handle[i]); 1483 + else 1484 + break; 1485 + } 1488 1486 1489 - free_request_irq: 1490 1487 free_irq(hba->pcidev->irq, hba); 1491 1488 1492 1489 unmap_pci_bar: ··· 1559 1546 { 1560 1547 struct Scsi_Host *host = pci_get_drvdata(pcidev); 1561 1548 struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata; 1549 + u32 i; 1562 1550 1563 1551 dprintk("scsi%d: hptiop_remove\n", hba->host->host_no); 1564 1552 ··· 1569 1555 1570 1556 free_irq(hba->pcidev->irq, hba); 1571 1557 1572 - dma_free_coherent(&hba->pcidev->dev, 1573 - hba->req_size * hba->max_requests + 0x20, 1574 - hba->dma_coherent, 1575 - hba->dma_coherent_handle); 1558 + for (i = 0; i < hba->max_requests; i++) { 1559 + if (hba->dma_coherent[i] && hba->dma_coherent_handle[i]) 1560 + dma_free_coherent(&hba->pcidev->dev, 1561 + hba->req_size + 0x20, 1562 + hba->dma_coherent[i], 1563 + hba->dma_coherent_handle[i]); 1564 + else 1565 + break; 1566 + } 1576 1567 1577 1568 hba->ops->internal_memfree(hba); 1578 1569 ··· 1672 1653 { PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops }, 1673 1654 { PCI_VDEVICE(TTI, 0x4520), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1674 1655 { PCI_VDEVICE(TTI, 0x4522), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1656 + { PCI_VDEVICE(TTI, 0x3610), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1657 + { PCI_VDEVICE(TTI, 0x3611), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1658 + { PCI_VDEVICE(TTI, 0x3620), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1659 + { PCI_VDEVICE(TTI, 0x3622), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1660 + { PCI_VDEVICE(TTI, 0x3640), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1661 + { PCI_VDEVICE(TTI, 0x3660), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1662 + { PCI_VDEVICE(TTI, 0x3680), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1663 + { PCI_VDEVICE(TTI, 0x3690), (kernel_ulong_t)&hptiop_mvfrey_ops }, 1675 1664 {}, 1676 1665 }; 1677 1666
+3 -3
drivers/scsi/hptiop.h
··· 1 1 /* 2 2 * HighPoint RR3xxx/4xxx controller driver for Linux 3 - * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights Reserved. 3 + * Copyright (C) 2006-2015 HighPoint Technologies, Inc. All Rights Reserved. 4 4 * 5 5 * This program is free software; you can redistribute it and/or modify 6 6 * it under the terms of the GNU General Public License as published by ··· 327 327 struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; 328 328 329 329 /* used to free allocated dma area */ 330 - void *dma_coherent; 331 - dma_addr_t dma_coherent_handle; 330 + void *dma_coherent[HPTIOP_MAX_REQUESTS]; 331 + dma_addr_t dma_coherent_handle[HPTIOP_MAX_REQUESTS]; 332 332 333 333 atomic_t reset_count; 334 334 atomic_t resetting;