USB: cdc_acm: Fix memory leak after hangup
[safe/jmp/linux-2.6] / drivers / scsi / BusLogic.c
index e874b89..1ddcf40 100644 (file)
@@ -304,18 +304,10 @@ static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
 static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
 {
        struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
-       struct scsi_cmnd *cmd = CCB->Command;
 
-       if (cmd->use_sg != 0) {
-               pci_unmap_sg(HostAdapter->PCI_Device,
-                               (struct scatterlist *)cmd->request_buffer,
-                               cmd->use_sg, cmd->sc_data_direction);
-       } else if (cmd->request_bufflen != 0) {
-               pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer,
-                               CCB->DataLength, cmd->sc_data_direction);
-       }
+       scsi_dma_unmap(CCB->Command);
        pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
-                       CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
+                        CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
 
        CCB->Command = NULL;
        CCB->Status = BusLogic_CCB_Free;
@@ -579,17 +571,17 @@ static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapt
        /*
           Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
         */
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe330)
                BusLogic_AppendProbeAddressISA(0x330);
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe334)
                BusLogic_AppendProbeAddressISA(0x334);
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe230)
                BusLogic_AppendProbeAddressISA(0x230);
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe234)
                BusLogic_AppendProbeAddressISA(0x234);
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe130)
                BusLogic_AppendProbeAddressISA(0x130);
-       if (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
+       if (!BusLogic_ProbeOptions.LimitedProbeISA || BusLogic_ProbeOptions.Probe134)
                BusLogic_AppendProbeAddressISA(0x134);
 }
 
@@ -675,7 +667,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
                if (pci_enable_device(PCI_Device))
                        continue;
 
-               if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK ))
+               if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32) ))
                        continue;
 
                Bus = PCI_Device->bus->number;
@@ -795,7 +787,9 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
           host adapters are probed.
         */
        if (!BusLogic_ProbeOptions.NoProbeISA)
-               if (PrimaryProbeInfo->IO_Address == 0 && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe330 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)) {
+               if (PrimaryProbeInfo->IO_Address == 0 &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe330)) {
                        PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
                        PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
                        PrimaryProbeInfo->IO_Address = 0x330;
@@ -805,15 +799,25 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
           omitting the Primary I/O Address which has already been handled.
         */
        if (!BusLogic_ProbeOptions.NoProbeISA) {
-               if (!StandardAddressSeen[1] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe334 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
+               if (!StandardAddressSeen[1] &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe334))
                        BusLogic_AppendProbeAddressISA(0x334);
-               if (!StandardAddressSeen[2] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe230 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
+               if (!StandardAddressSeen[2] &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe230))
                        BusLogic_AppendProbeAddressISA(0x230);
-               if (!StandardAddressSeen[3] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe234 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
+               if (!StandardAddressSeen[3] &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe234))
                        BusLogic_AppendProbeAddressISA(0x234);
-               if (!StandardAddressSeen[4] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe130 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
+               if (!StandardAddressSeen[4] &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe130))
                        BusLogic_AppendProbeAddressISA(0x130);
-               if (!StandardAddressSeen[5] && (BusLogic_ProbeOptions.LimitedProbeISA ? BusLogic_ProbeOptions.Probe134 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
+               if (!StandardAddressSeen[5] &&
+                               (!BusLogic_ProbeOptions.LimitedProbeISA ||
+                                BusLogic_ProbeOptions.Probe134))
                        BusLogic_AppendProbeAddressISA(0x134);
        }
        /*
@@ -830,7 +834,7 @@ static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAd
                if (pci_enable_device(PCI_Device))
                        continue;
 
-               if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
+               if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
                        continue;
 
                Bus = PCI_Device->bus->number;
@@ -884,7 +888,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
                if (pci_enable_device(PCI_Device))
                        continue;
 
-               if (pci_set_dma_mask(PCI_Device, DMA_32BIT_MASK))
+               if (pci_set_dma_mask(PCI_Device, DMA_BIT_MASK(32)))
                        continue;
 
                Bus = PCI_Device->bus->number;
@@ -892,7 +896,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
                IRQ_Channel = PCI_Device->irq;
                IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
                PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
+#ifdef CONFIG_SCSI_FLASHPOINT
                if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
                        BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
                        BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
@@ -1002,6 +1006,9 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
 }
 
 
+#else
+#define BusLogic_InitializeProbeInfoList(adapter) \
+               BusLogic_InitializeProbeInfoListISA(adapter)
 #endif                         /* CONFIG_PCI */
 
 
@@ -2220,22 +2227,35 @@ static int __init BusLogic_init(void)
                HostAdapter->PCI_Device = ProbeInfo->PCI_Device;
                HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
                HostAdapter->AddressCount = BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
+
+               /*
+                  Make sure region is free prior to probing.
+                */
+               if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
+                                       "BusLogic"))
+                       continue;
                /*
                   Probe the Host Adapter.  If unsuccessful, abort further initialization.
                 */
-               if (!BusLogic_ProbeHostAdapter(HostAdapter))
+               if (!BusLogic_ProbeHostAdapter(HostAdapter)) {
+                       release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
                        continue;
+               }
                /*
                   Hard Reset the Host Adapter.  If unsuccessful, abort further
                   initialization.
                 */
-               if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true))
+               if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) {
+                       release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
                        continue;
+               }
                /*
                   Check the Host Adapter.  If unsuccessful, abort further initialization.
                 */
-               if (!BusLogic_CheckHostAdapter(HostAdapter))
+               if (!BusLogic_CheckHostAdapter(HostAdapter)) {
+                       release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
                        continue;
+               }
                /*
                   Initialize the Driver Options field if provided.
                 */
@@ -2247,16 +2267,6 @@ static int __init BusLogic_init(void)
                 */
                BusLogic_AnnounceDriver(HostAdapter);
                /*
-                  Register usage of the I/O Address range.  From this point onward, any
-                  failure will be assumed to be due to a problem with the Host Adapter,
-                  rather than due to having mistakenly identified this port as belonging
-                  to a BusLogic Host Adapter.  The I/O Address range will not be
-                  released, thereby preventing it from being incorrectly identified as
-                  any other type of Host Adapter.
-                */
-               if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount, "BusLogic"))
-                       continue;
-               /*
                   Register the SCSI Host structure.
                 */
 
@@ -2280,6 +2290,12 @@ static int __init BusLogic_init(void)
                   Acquire the System Resources necessary to use the Host Adapter, then
                   Create the Initial CCBs, Initialize the Host Adapter, and finally
                   perform Target Device Inquiry.
+
+                  From this point onward, any failure will be assumed to be due to a
+                  problem with the Host Adapter, rather than due to having mistakenly
+                  identified this port as belonging to a BusLogic Host Adapter.  The
+                  I/O Address range will not be released, thereby preventing it from
+                  being incorrectly identified as any other type of Host Adapter.
                 */
                if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
                    BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
@@ -2627,7 +2643,8 @@ static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapt
                         */
                        if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 && CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally) {
                                struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[CCB->TargetID];
-                               struct SCSI_Inquiry *InquiryResult = (struct SCSI_Inquiry *) Command->request_buffer;
+                               struct SCSI_Inquiry *InquiryResult =
+                                       (struct SCSI_Inquiry *) scsi_sglist(Command);
                                TargetFlags->TargetExists = true;
                                TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
                                TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
@@ -2798,9 +2815,8 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
        int CDB_Length = Command->cmd_len;
        int TargetID = Command->device->id;
        int LogicalUnit = Command->device->lun;
-       void *BufferPointer = Command->request_buffer;
-       int BufferLength = Command->request_bufflen;
-       int SegmentCount = Command->use_sg;
+       int BufferLength = scsi_bufflen(Command);
+       int Count;
        struct BusLogic_CCB *CCB;
        /*
           SCSI REQUEST_SENSE commands will be executed automatically by the Host
@@ -2830,36 +2846,35 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
                        return 0;
                }
        }
+
        /*
           Initialize the fields in the BusLogic Command Control Block (CCB).
         */
-       if (SegmentCount == 0 && BufferLength != 0) {
-               CCB->Opcode = BusLogic_InitiatorCCB;
-               CCB->DataLength = BufferLength;
-               CCB->DataPointer = pci_map_single(HostAdapter->PCI_Device,
-                               BufferPointer, BufferLength,
-                               Command->sc_data_direction);
-       } else if (SegmentCount != 0) {
-               struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
-               int Segment, Count;
-
-               Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
-                               Command->sc_data_direction);
+       Count = scsi_dma_map(Command);
+       BUG_ON(Count < 0);
+       if (Count) {
+               struct scatterlist *sg;
+               int i;
+
                CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
                CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
                if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
                        CCB->DataPointer = (unsigned int) CCB->DMA_Handle + ((unsigned long) &CCB->ScatterGatherList - (unsigned long) CCB);
                else
                        CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
-               for (Segment = 0; Segment < Count; Segment++) {
-                       CCB->ScatterGatherList[Segment].SegmentByteCount = sg_dma_len(ScatterList + Segment);
-                       CCB->ScatterGatherList[Segment].SegmentDataPointer = sg_dma_address(ScatterList + Segment);
+
+               scsi_for_each_sg(Command, sg, Count, i) {
+                       CCB->ScatterGatherList[i].SegmentByteCount =
+                               sg_dma_len(sg);
+                       CCB->ScatterGatherList[i].SegmentDataPointer =
+                               sg_dma_address(sg);
                }
-       } else {
+       } else if (!Count) {
                CCB->Opcode = BusLogic_InitiatorCCB;
                CCB->DataLength = BufferLength;
                CCB->DataPointer = 0;
        }
+
        switch (CDB[0]) {
        case READ_6:
        case READ_10:
@@ -2935,7 +2950,7 @@ static int BusLogic_QueueCommand(struct scsi_cmnd *Command, void (*CompletionRou
                }
        }
        memcpy(CCB->CDB, CDB, CDB_Length);
-       CCB->SenseDataLength = sizeof(Command->sense_buffer);
+       CCB->SenseDataLength = SCSI_SENSE_BUFFERSIZE;
        CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device, Command->sense_buffer, CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
        CCB->Command = Command;
        Command->scsi_done = CompletionRoutine;
@@ -3598,6 +3613,7 @@ static void __exit BusLogic_exit(void)
 
 __setup("BusLogic=", BusLogic_Setup);
 
+#ifdef MODULE
 static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
        { PCI_VENDOR_ID_BUSLOGIC, PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
@@ -3607,6 +3623,7 @@ static struct pci_device_id BusLogic_pci_tbl[] __devinitdata = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { }
 };
+#endif
 MODULE_DEVICE_TABLE(pci, BusLogic_pci_tbl);
 
 module_init(BusLogic_init);