hptiop: HighPoint RocketRAID 3xxx controller driver
Subsystems (2)
HighPoint Linux Team
maintainerQuoted 11 lines · James Bottomley
_req = get_req(hba); if (_req == NULL) { dprintk("hptiop_queuecmd : no free req\n"); scp->result = DID_BUS_BUSY << 16; goto cmd_done; }This should be doing a return
SCSI_MLQUEUE_HOST_BUSY.DID_BUS_BUSYdoesn't do the resource contention counting that you want (MLQUEUE_HOST_BUSYwill wait until a command returns ... presumably freeing up resources before trying another).
Right, this should be modified.
Quoted 10 lines
/* * hptiop_shutdown will flash controller cache. */ if (scp->cmnd[0] == SYNCHRONIZE_CACHE) { scp->result = DID_OK<<16; goto cmd_done; }Are you really sure you want to do this? It looks like we'll be doing this in cases where shutdown won't be called (like suspend).
These lines should be removed. The controller firmware will response to SYNCHRONIZE_CACHE command.
Quoted 6 lines
host->can_queue = le32_to_cpu(iop_config.max_requests); host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);You might want to think about adjusting this. For the single LUN case, it's fine. For the multi-lun case it may allow commands to a single LUN to starve everything else.
There will be no multi-lun support for the controller so this is not an issue.
---
drivers/scsi/hptiop.c +1 -9
@@ -504,18 +504,10 @@ static int hptiop_queuecommand(struct scBUG_ON (!done); scp->scsi_done = done; -/* -* hptiop_shutdown will flash controller cache. -*/ -if (scp->cmnd[0 ] ==SYNCHRONIZE_CACHE ) { - scp->result =DID_OK <<16 ; - goto cmd_done; - } - _req =get_req (hba);if (_req ==NULL ) {dprintk ("hptiop_queuecmd : no free req\n" ); - scp->result =DID_BUS_BUSY <<16 ; + scp->result =SCSI_MLQUEUE_HOST_BUSY ; goto cmd_done; }
HighPoint Linux Team
maintainerQuoted 10 lines · HighPoint Linux Team
Quoted 7 lines
host->can_queue = le32_to_cpu(iop_config.max_requests); host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);You might want to think about adjusting this. For the single LUN case, it's fine. For the multi-lun case it may allow commands to a single LUN to starve everything else.
There will be no multi-lun support for the controller so this is not an issue.
Sorry, a mistake. Multi-lun is supported.
Should host->can_queue be set to (cmd_per_lun * max_lun) ?
Quoted 11 lines · HighPoint Linux Team
drivers/scsi/hptiop.c +0
-5@@ -504,18 +504,10 @@ static int hptiop_queuecommand(struct scBUG_ON (!done); scp->scsi_done = done; -/* -* hptiop_shutdown will flash controller cache. -*/ -if (scp->cmnd[0 ] ==SYNCHRONIZE_CACHE ) { - scp->result =DID_OK <<16 ;
drivers/scsi/hptiop.c static int hptiop_queuecommand(struct sc · line 512
Quoted 10 lines
drivers/scsi/hptiop.c +1
-4- goto cmd_done; - } - _req =get_req (hba);if (_req ==NULL ) {dprintk ("hptiop_queuecmd : no free req\n" ); - scp->result =DID_BUS_BUSY <<16 ; + scp->result =SCSI_MLQUEUE_HOST_BUSY ; goto cmd_done; }
Close. For the last bit of code quoted above, you should return SCSI_MLQUEUE_HOST_BUSY as your ->queuecommand() return code, rather than setting scp->result and calling the done() hook.
Jeff
drivers/scsi/hptiop.c static int hptiop_queuecommand(struct sc · line 511
Quoted 4 lines · HighPoint Linux Team
dprintk("hptiop_queuecmd : no free req\n");drivers/scsi/hptiop.c +1
-1- scp->result =DID_BUS_BUSY <<16 ; + scp->result =SCSI_MLQUEUE_HOST_BUSY ; goto cmd_done;
As jeff said, this needs to become a return SCSI_MLQUEUE_HOST_BUSY.
Quoted 9 lines · HighPoint Linux Team
Quoted 8 lines
Quoted 7 lines
host->can_queue = le32_to_cpu(iop_config.max_requests); host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);You might want to think about adjusting this. For the single LUN case, it's fine. For the multi-lun case it may allow commands to a single LUN to starve everything else.
Quoted 5 lines
Quoted 2 lines
There will be no multi-lun support for the controller so this is not an issue.
Sorry, a mistake. Multi-lun is supported.
Shouldhost->can_queuebe set to (cmd_per_lun*max_lun) ?
It depends on how the controller behaves. Setting can_queue and cmd_per_lun tends to work for most SCSI controllers because the actual scsi devices have queue depths << this number. If your controller will behave like this (i.e. will not allow the internal queue for a single lun to fill up to this depth) then you can keep this setting (although, again, since this is probably fixed by the firmware, you want to set cmd_per_lun to this value to avoid excessive QUEUE_FULL returns). If the controller will happily load all the available slots up for a single lun, then you might want to think about reducing cmd_per_lun to some fraction of can_queue (you could even set it to can_queue - 2 like the 3ware controller).
Most of the other actual raid controllers seem to have much smaller per-lun queues, so they mainly set smaller, fixed size values for cmd_per_lun.
James
HighPoint Linux Team
maintainerQuoted 13 lines · James Bottomley
Quoted 1 line
Should
host->can_queuebe set to (cmd_per_lun*max_lun) ?It depends on how the controller behaves. Setting
can_queueandcmd_per_luntends to work for most SCSI controllers because the actual scsi devices have queue depths << this number. If your controller will behave like this (i.e. will not allow the internal queue for a single lun to fill up to this depth) then you can keep this setting (although, again, since this is probably fixed by the firmware, you want to setcmd_per_lunto this value to avoid excessiveQUEUE_FULLreturns). If the controller will happily load all the available slots up for a single lun, then you might want to think about reducingcmd_per_lunto some fraction ofcan_queue(you could even set it tocan_queue- 2 like the 3ware controller).
The hptiop firmware works as the latter case. Should it be modified like this:
host->can_queue = le32_to_cpu(iop_config.max_requests);
- host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
+ host->cmd_per_lun = host->can_queue - 2;
While the 3ware driver sets both can_queue and cmd_per_lun to 254:
(3w-9xxx.h)
#define TW_Q_LENGTH 256
#define TW_MAX_CMDS_PER_LUN 254
(3w-9xxx.c)
.can_queue = TW_Q_LENGTH-2,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN
Should can_queue be set to TW_Q_LENGTH ?
HighPoint Linux Team
HighPoint Linux Team
maintainerUpdates:
- don't bypass SYNCHRONIZE_CACHE command
- return SCSI_MLQUEUE_HOST_BUSY when no free request slots
- move scsi_remove_host() to the begin of hpt_remove(), or it will not work after resources being released.
---
drivers/scsi/hptiop.c +3 -11
@@ -504,19 +504,10 @@ static int hptiop_queuecommand(struct scBUG_ON (!done); scp->scsi_done = done; -/* -* hptiop_shutdown will flash controller cache. -*/ -if (scp->cmnd[0 ] ==SYNCHRONIZE_CACHE ) { - scp->result =DID_OK <<16 ; - goto cmd_done; - } - _req =get_req (hba);if (_req ==NULL ) {dprintk ("hptiop_queuecmd : no free req\n" ); - scp->result =DID_BUS_BUSY <<16 ; - goto cmd_done; +return SCSI_MLQUEUE_HOST_BUSY ; } _req->scp = scp;
@@ -1429,6 +1420,8 @@ static void hptiop_remove(struct pci_devdprintk ("scsi%d: hptiop_remove\n" , hba->host->host_no); +scsi_remove_host (host); +spin_lock (&hptiop_hba_list_lock);list_del_init (&hba->link);spin_unlock (&hptiop_hba_list_lock);
@@ -1448,7 +1441,6 @@ static void hptiop_remove(struct pci_devpci_set_drvdata (hba->pcidev,NULL );pci_disable_device (hba->pcidev); -scsi_remove_host (host);scsi_host_put (host); }
HighPoint Linux Team
maintainerPATCH 1/1 hptiop: wrong register used in hptiop_reset_hba()
IOP reset message should be posted to inbound message register instead of outbound message register.
---
drivers/scsi/hptiop.c +1 -1
@@ -577,7 +577,7 @@ static int hptiop_reset_hba(struct hptioif (atomic_xchg (&hba->resetting,1 ) ==0 ) {atomic_inc (&hba->reset_count);writel (IOPMU_INBOUND_MSG0_RESET , - &hba->iop->outbound_msgaddr0); + &hba->iop->inbound_msgaddr0);hptiop_pci_posting_flush (hba->iop); }