Commit 12c262b2 authored by James Bottomley's avatar James Bottomley

Merge mulgrave.(none):/home/jejb/BK/scsi-cpqfc-2.5

into mulgrave.(none):/home/jejb/BK/scsi-for-linus-2.5
parents 378a8995 bd381b1f
...@@ -7,11 +7,18 @@ Tested in single and dual HBA configuration, 32 and 64bit busses, ...@@ -7,11 +7,18 @@ Tested in single and dual HBA configuration, 32 and 64bit busses,
SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc() SEST size 512 Exchanges (simultaneous I/Os) limited by module kmalloc()
max of 128k bytes contiguous. max of 128k bytes contiguous.
Ver 2.5.3 Aug 01, 2002
* fix the passthru ioctl to handle the Scsi_Cmnd->request being a pointer
Ver 2.5.1 Jul 30, 2002
* fix ioctl to pay attention to the specified LUN.
Ver 2.5.0 Nov 29, 2001 Ver 2.5.0 Nov 29, 2001
* eliminated io_request_lock. This change makes the driver specific * eliminated io_request_lock. This change makes the driver specific
to the 2.5.x kernels. to the 2.5.x kernels.
* silenced excessively noisy printks. * silenced excessively noisy printks.
Ver 2.1.2 July 23, 2002
* initialize DumCmnd->lun in cpqfcTS_ioctl (used in fcFindLoggedInPorts as LUN index)
Ver 2.1.1 Oct 18, 2001 Ver 2.1.1 Oct 18, 2001
* reinitialize Cmnd->SCp.sent_command (used to identify commands as * reinitialize Cmnd->SCp.sent_command (used to identify commands as
passthrus) on calling scsi_done, since the scsi mid layer does not passthrus) on calling scsi_done, since the scsi mid layer does not
......
This diff is collapsed.
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
// don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c // don't forget to also change MODULE_DESCRIPTION in cpqfcTSinit.c
#define VER_MAJOR 2 #define VER_MAJOR 2
#define VER_MINOR 5 #define VER_MINOR 5
#define VER_SUBMINOR 0 #define VER_SUBMINOR 3
// Macros for kernel (esp. SMP) tracing using a PCI analyzer // Macros for kernel (esp. SMP) tracing using a PCI analyzer
// (e.g. x86). // (e.g. x86).
...@@ -907,9 +907,17 @@ typedef struct ...@@ -907,9 +907,17 @@ typedef struct
} FC_SCSI_QUE, *PFC_SCSI_QUE; } FC_SCSI_QUE, *PFC_SCSI_QUE;
typedef struct {
/* This is tacked on to a Scsi_Request in upper_private_data
for pasthrough ioctls, as a place to hold data that can't
be stashed anywhere else in the Scsi_Request. We differentiate
this from _real_ upper_private_data by checking if the virt addr
is within our special pool. */
ushort bus;
ushort pdrive;
} cpqfc_passthru_private_t;
#define CPQFC_MAX_PASSTHRU_CMDS 100
#define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST #define DYNAMIC_ALLOCATIONS 4 // Tachyon aligned allocations: ERQ,IMQ,SFQ,SEST
...@@ -949,6 +957,8 @@ typedef struct ...@@ -949,6 +957,8 @@ typedef struct
PFC_LINK_QUE fcLQ; // the WorkerThread operates on this PFC_LINK_QUE fcLQ; // the WorkerThread operates on this
spinlock_t hba_spinlock; // held/released by WorkerThread spinlock_t hba_spinlock; // held/released by WorkerThread
cpqfc_passthru_private_t *private_data_pool;
unsigned long *private_data_bits;
} CPQFCHBA; } CPQFCHBA;
...@@ -1405,6 +1415,7 @@ struct ext_sg_entry_t { ...@@ -1405,6 +1415,7 @@ struct ext_sg_entry_t {
__u32 lba; /* lower bus address bits 0-31 */ __u32 lba; /* lower bus address bits 0-31 */
}; };
// J. McCarty's LINK.H // J. McCarty's LINK.H
// //
// LS_RJT Reason Codes // LS_RJT Reason Codes
......
...@@ -2887,15 +2887,22 @@ static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd) ...@@ -2887,15 +2887,22 @@ static void ScsiReportLunsDone(Scsi_Cmnd *Cmnd)
Done: Done:
} }
extern int is_private_data_of_cpqfc(CPQFCHBA *hba, void * pointer);
extern void cpqfc_free_private_data(CPQFCHBA *hba, cpqfc_passthru_private_t *data);
static void static void
call_scsi_done(Scsi_Cmnd *Cmnd) call_scsi_done(Scsi_Cmnd *Cmnd)
{ {
// We have to reinitialize sent_command here, so the scsi-mid CPQFCHBA *hba;
// layer won't re-use the scsi command leaving it set incorrectly. hba = (CPQFCHBA *) Cmnd->host->hostdata;
// (incorrectly for our purposes...it's normally unused.) // Was this command a cpqfc passthru ioctl ?
if (Cmnd->sc_request != NULL && Cmnd->host != NULL &&
if (Cmnd->SCp.sent_command != 0) { // was it a passthru? Cmnd->host->hostdata != NULL &&
Cmnd->SCp.sent_command = 0; is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata,
Cmnd->sc_request->upper_private_data)) {
cpqfc_free_private_data(hba,
Cmnd->sc_request->upper_private_data);
Cmnd->sc_request->upper_private_data = NULL;
Cmnd->result &= 0xff00ffff; Cmnd->result &= 0xff00ffff;
Cmnd->result |= (DID_PASSTHROUGH << 16); // prevents retry Cmnd->result |= (DID_PASSTHROUGH << 16); // prevents retry
} }
...@@ -3293,6 +3300,7 @@ static int GetLoopID( ULONG al_pa ) ...@@ -3293,6 +3300,7 @@ static int GetLoopID( ULONG al_pa )
} }
#endif #endif
extern cpqfc_passthru_private_t *cpqfc_private(Scsi_Request *sr);
// Search the singly (forward) linked list "fcPorts" looking for // Search the singly (forward) linked list "fcPorts" looking for
// either the SCSI target (if != -1), port_id (if not NULL), // either the SCSI target (if != -1), port_id (if not NULL),
...@@ -3366,8 +3374,18 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort( ...@@ -3366,8 +3374,18 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort(
{ {
// For "passthru" modes, the IOCTL caller is responsible // For "passthru" modes, the IOCTL caller is responsible
// for setting the FCP-LUN addressing // for setting the FCP-LUN addressing
if( !Cmnd->SCp.sent_command ) // NOT passthru? if (Cmnd->sc_request != NULL && Cmnd->host != NULL &&
{ Cmnd->host->hostdata != NULL &&
is_private_data_of_cpqfc((CPQFCHBA *) Cmnd->host->hostdata,
Cmnd->sc_request->upper_private_data)) {
/* This is a passthru... */
cpqfc_passthru_private_t *pd;
pd = Cmnd->sc_request->upper_private_data;
Cmnd->SCp.phase = pd->bus;
// Cmnd->SCp.have_data_in = pd->pdrive;
Cmnd->SCp.have_data_in = Cmnd->lun;
} else {
/* This is not a passthru... */
// set the FCP-LUN addressing type // set the FCP-LUN addressing type
Cmnd->SCp.phase = pLoggedInPort->ScsiNexus.VolumeSetAddressing; Cmnd->SCp.phase = pLoggedInPort->ScsiNexus.VolumeSetAddressing;
...@@ -3380,6 +3398,8 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort( ...@@ -3380,6 +3398,8 @@ PFC_LOGGEDIN_PORT fcFindLoggedInPort(
// Report Luns command // Report Luns command
if( pLoggedInPort->ScsiNexus.LunMasking == 1) if( pLoggedInPort->ScsiNexus.LunMasking == 1)
{ {
if (Cmnd->lun > sizeof(pLoggedInPort->ScsiNexus.lun))
return NULL;
// we KNOW all the valid LUNs... 0xFF is invalid! // we KNOW all the valid LUNs... 0xFF is invalid!
Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->lun]; Cmnd->SCp.have_data_in = pLoggedInPort->ScsiNexus.lun[Cmnd->lun];
if (pLoggedInPort->ScsiNexus.lun[Cmnd->lun] == 0xFF) if (pLoggedInPort->ScsiNexus.lun[Cmnd->lun] == 0xFF)
...@@ -3504,7 +3524,6 @@ static void UnblockScsiDevice( struct Scsi_Host *HostAdapter, ...@@ -3504,7 +3524,6 @@ static void UnblockScsiDevice( struct Scsi_Host *HostAdapter,
{ {
printk("LinkDnCmnd scsi_done ptr null, port_id %Xh\n", printk("LinkDnCmnd scsi_done ptr null, port_id %Xh\n",
pLoggedInPort->port_id); pLoggedInPort->port_id);
Cmnd->SCp.sent_command = 0;
} }
else else
call_scsi_done(Cmnd); call_scsi_done(Cmnd);
...@@ -5232,7 +5251,6 @@ static ULONG build_SEST_sgList( ...@@ -5232,7 +5251,6 @@ static ULONG build_SEST_sgList(
sgl = (struct scatterlist*)Cmnd->request_buffer; sgl = (struct scatterlist*)Cmnd->request_buffer;
sg_count = pci_map_sg(pcidev, sgl, Cmnd->use_sg, sg_count = pci_map_sg(pcidev, sgl, Cmnd->use_sg,
scsi_to_pci_dma_dir(Cmnd->sc_data_direction)); scsi_to_pci_dma_dir(Cmnd->sc_data_direction));
// printk("sgl = %p, sg_count = %d\n", (void *) sgl, sg_count);
if( sg_count <= 3 ) { if( sg_count <= 3 ) {
// we need to be careful here that no individual mapping // we need to be careful here that no individual mapping
...@@ -5261,7 +5279,6 @@ static ULONG build_SEST_sgList( ...@@ -5261,7 +5279,6 @@ static ULONG build_SEST_sgList(
// printk("totalsgs = %d, sgcount=%d\n",totalsgs,sg_count); // printk("totalsgs = %d, sgcount=%d\n",totalsgs,sg_count);
} }
// printk("totalsgs = %d, sgcount=%d\n", totalsgs, sg_count);
if( totalsgs <= 3 ) // can (must) use "local" SEST list if( totalsgs <= 3 ) // can (must) use "local" SEST list
{ {
while( bytes_to_go) while( bytes_to_go)
...@@ -6164,13 +6181,11 @@ void cpqfcTSCompleteExchange( ...@@ -6164,13 +6181,11 @@ void cpqfcTSCompleteExchange(
} }
else else
{ {
Exchanges->fcExchange[ x_ID ].Cmnd->SCp.sent_command = 0;
// printk(" not calling scsi_done on x_ID %Xh, Cmnd %p\n", // printk(" not calling scsi_done on x_ID %Xh, Cmnd %p\n",
// x_ID, Exchanges->fcExchange[ x_ID ].Cmnd); // x_ID, Exchanges->fcExchange[ x_ID ].Cmnd);
} }
} }
else{ else{
Exchanges->fcExchange[ x_ID ].Cmnd->SCp.sent_command = 0;
printk(" x_ID %Xh, type %Xh, Cdb0 %Xh\n", x_ID, printk(" x_ID %Xh, type %Xh, Cdb0 %Xh\n", x_ID,
Exchanges->fcExchange[ x_ID ].type, Exchanges->fcExchange[ x_ID ].type,
Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0]); Exchanges->fcExchange[ x_ID ].Cmnd->cmnd[0]);
...@@ -6463,10 +6478,10 @@ static int build_FCP_payload( Scsi_Cmnd *Cmnd, ...@@ -6463,10 +6478,10 @@ static int build_FCP_payload( Scsi_Cmnd *Cmnd,
for( i=0; (i < Cmnd->cmd_len) && i < MAX_COMMAND_SIZE; i++) for( i=0; (i < Cmnd->cmd_len) && i < MAX_COMMAND_SIZE; i++)
*payload++ = Cmnd->cmnd[i]; *payload++ = Cmnd->cmnd[i];
if( Cmnd->cmd_len == 16 ) // if( Cmnd->cmd_len == 16 )
{ // {
memcpy( payload, &Cmnd->SCp.buffers_residual, 4); // memcpy( payload, &Cmnd->SCp.buffers_residual, 4);
} // }
payload+= (16 - i); payload+= (16 - i);
// FCP_DL is largest number of expected data bytes // FCP_DL is largest number of expected data bytes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment