[PATCH][SCSI] hptiop: Support HighPoint RR36xx HBAs and Support SAS tape and SAS media changer

From: linux
Date: Tue Jun 23 2015 - 23:41:33 EST


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

Signed-off-by: HighPoint Linux Team <linux@xxxxxxxxxxxxxxxxxx>

drivers/scsi/hptiop.c | 104
+++++++++++++++++++++++++++++++++++++++------------------------
drivers/scsi/hptiop.h | 6 +--
2 files changed, 69 insertions(+), 41 deletions(-)

diff -urN linux.git/drivers/scsi/hptiop.c linux/drivers/scsi/hptiop.c
--- linux.git/drivers/scsi/hptiop.c 2015-06-08 01:48:38.093750000 -0400
+++ linux/drivers/scsi/hptiop.c 2015-06-08 02:45:33.234375000 -0400
@@ -1,6 +1,6 @@
/*
* HighPoint RR3xxx/4xxx controller driver for Linux
- * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights
Reserved.
+ * Copyright (C) 2006-2015 HighPoint Technologies, Inc. All Rights
Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,7 +42,7 @@

static char driver_name[] = "hptiop";
static const char driver_name_long[] = "RocketRAID 3xxx/4xxx Controller
driver";
-static const char driver_ver[] = "v1.8";
+static const char driver_ver[] = "v1.10.0";

static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32
millisec);
static void hptiop_finish_scsi_req(struct hptiop_hba *hba, u32 tag,
@@ -764,9 +764,7 @@
scsi_set_resid(scp,
scsi_bufflen(scp) -
le32_to_cpu(req->dataxfer_length));
scp->result = SAM_STAT_CHECK_CONDITION;
- memcpy(scp->sense_buffer, &req->sg_list,
- min_t(size_t, SCSI_SENSE_BUFFERSIZE,
- le32_to_cpu(req->dataxfer_length)));
+ memcpy(scp->sense_buffer, &req->sg_list,
SCSI_SENSE_BUFFERSIZE);
goto skip_resid;
break;

@@ -1036,9 +1034,10 @@
_req->index, _req->req_virt);

scp->result = 0;
-
- if (scp->device->channel || scp->device->lun ||
- scp->device->id > hba->max_devices) {
+
+ if (scp->device->channel ||
+ (scp->device->id > hba->max_devices) ||
+ ((scp->device->id == (hba->max_devices-1)) &&
scp->device->lun)) {
scp->result = DID_BAD_TARGET << 16;
free_req(hba, _req);
goto cmd_done;
@@ -1168,6 +1167,14 @@
NULL
};

+static int hptiop_slave_config(struct scsi_device *sdev)
+{
+ if (sdev->type == TYPE_TAPE)
+ blk_queue_max_hw_sectors(sdev->request_queue, 8192);
+
+ return 0;
+}
+
static struct scsi_host_template driver_template = {
.module = THIS_MODULE,
.name = driver_name,
@@ -1179,6 +1186,7 @@
.use_clustering = ENABLE_CLUSTERING,
.proc_name = driver_name,
.shost_attrs = hptiop_attrs,
+ .slave_configure = hptiop_slave_config,
.this_id = -1,
.change_queue_depth = hptiop_adjust_disk_queue_depth,
};
@@ -1323,7 +1331,8 @@
}

hba = (struct hptiop_hba *)host->hostdata;
-
+ memset(hba, 0, sizeof(struct hptiop_hba));
+
hba->ops = iop_ops;
hba->pcidev = pcidev;
hba->host = host;
@@ -1336,7 +1345,7 @@
init_waitqueue_head(&hba->reset_wq);
init_waitqueue_head(&hba->ioctl_wq);

- host->max_lun = 1;
+ host->max_lun = 128;
host->max_channel = 0;
host->io_port = 0;
host->n_io_port = 0;
@@ -1428,34 +1437,33 @@
dprintk("req_size=%d, max_requests=%d\n", req_size,
hba->max_requests);

hba->req_size = req_size;
- start_virt = dma_alloc_coherent(&pcidev->dev,
- hba->req_size*hba->max_requests + 0x20,
- &start_phy, GFP_KERNEL);
-
- if (!start_virt) {
- printk(KERN_ERR "scsi%d: fail to alloc request mem\n",
- hba->host->host_no);
- goto free_request_irq;
- }
-
- hba->dma_coherent = start_virt;
- hba->dma_coherent_handle = start_phy;
-
- if ((start_phy & 0x1f) != 0) {
- offset = ((start_phy + 0x1f) & ~0x1f) - start_phy;
- start_phy += offset;
- start_virt += offset;
- }
-
hba->req_list = NULL;
+
for (i = 0; i < hba->max_requests; i++) {
+ start_virt = dma_alloc_coherent(&pcidev->dev,
+ hba->req_size + 0x20,
+ &start_phy, GFP_KERNEL);
+
+ if (!start_virt) {
+ printk(KERN_ERR "scsi%d: fail to alloc request
mem\n",
+ hba->host->host_no);
+ goto free_request_mem;
+ }
+
+ hba->dma_coherent[i] = start_virt;
+ hba->dma_coherent_handle[i] = start_phy;
+
+ if ((start_phy & 0x1f) != 0) {
+ offset = ((start_phy + 0x1f) & ~0x1f) - start_phy;
+ start_phy += offset;
+ start_virt += offset;
+ }
+
hba->reqs[i].next = NULL;
hba->reqs[i].req_virt = start_virt;
hba->reqs[i].req_shifted_phy = start_phy >> 5;
hba->reqs[i].index = i;
free_req(hba, &hba->reqs[i]);
- start_virt = (char *)start_virt + hba->req_size;
- start_phy = start_phy + hba->req_size;
}

/* Enable Interrupt and start background task */
@@ -1474,9 +1482,15 @@
return 0;

free_request_mem:
- dma_free_coherent(&hba->pcidev->dev,
- hba->req_size * hba->max_requests + 0x20,
- hba->dma_coherent, hba->dma_coherent_handle);
+ for (i = 0; i < hba->max_requests; i++) {
+ if (hba->dma_coherent[i] && hba->dma_coherent_handle[i])
+ dma_free_coherent(&hba->pcidev->dev,
+ hba->req_size + 0x20,
+ hba->dma_coherent[i],
+ hba->dma_coherent_handle[i]);
+ else
+ break;
+ }

free_request_irq:
free_irq(hba->pcidev->irq, hba);
@@ -1546,6 +1560,7 @@
{
struct Scsi_Host *host = pci_get_drvdata(pcidev);
struct hptiop_hba *hba = (struct hptiop_hba *)host->hostdata;
+ u32 i;

dprintk("scsi%d: hptiop_remove\n", hba->host->host_no);

@@ -1555,10 +1570,15 @@

free_irq(hba->pcidev->irq, hba);

- dma_free_coherent(&hba->pcidev->dev,
- hba->req_size * hba->max_requests + 0x20,
- hba->dma_coherent,
- hba->dma_coherent_handle);
+ for (i = 0; i < hba->max_requests; i++) {
+ if (hba->dma_coherent[i] && hba->dma_coherent_handle[i])
+ dma_free_coherent(&hba->pcidev->dev,
+ hba->req_size + 0x20,
+ hba->dma_coherent[i],
+ hba->dma_coherent_handle[i]);
+ else
+ break;
+ }

hba->ops->internal_memfree(hba);

@@ -1653,6 +1673,14 @@
{ PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops },
{ PCI_VDEVICE(TTI, 0x4520), (kernel_ulong_t)&hptiop_mvfrey_ops },
{ PCI_VDEVICE(TTI, 0x4522), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3610), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3611), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3620), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3622), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3640), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3660), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3680), (kernel_ulong_t)&hptiop_mvfrey_ops },
+ { PCI_VDEVICE(TTI, 0x3690), (kernel_ulong_t)&hptiop_mvfrey_ops },
{},
};

diff -urN linux.git/drivers/scsi/hptiop.h linux/drivers/scsi/hptiop.h
--- linux.git/drivers/scsi/hptiop.h 2015-06-08 01:49:36.734375000 -0400
+++ linux/drivers/scsi/hptiop.h 2015-06-08 02:15:44.421875000 -0400
@@ -1,6 +1,6 @@
/*
* HighPoint RR3xxx/4xxx controller driver for Linux
- * Copyright (C) 2006-2012 HighPoint Technologies, Inc. All Rights
Reserved.
+ * Copyright (C) 2006-2015 HighPoint Technologies, Inc. All Rights
Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -327,8 +327,8 @@
struct hptiop_request reqs[HPTIOP_MAX_REQUESTS];

/* used to free allocated dma area */
- void *dma_coherent;
- dma_addr_t dma_coherent_handle;
+ void *dma_coherent[HPTIOP_MAX_REQUESTS];
+ dma_addr_t dma_coherent_handle[HPTIOP_MAX_REQUESTS];

atomic_t reset_count;
atomic_t resetting;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/