On Mon, 11 Aug 2003, Robert L. Harris wrote: > Bah, it went to kern.log. Attaching that compressed. If this isn't > what you want or is too much debugging let me know. This is the whole > log file incase something is mixed in the middle.
Okay, I see the problem with 2.6. It stems from a change I made but didn't examine carefully enough. The attached patch ought to fix things, bringing 2.6 up to the performance level of 2.4 -- I know that's not saying very much! But at least it's a start. If the patch works I'll submit it, so send another kernel log. The problem with 2.4 wasn't apparent from your log. It may be a problem involving the SCSI layer. usb-storage succeeded in probing and registering the drive and then didn't receive any more requests until you rmmod'ed it 30 seconds later. Alan Stern # This is a BitKeeper generated patch for the following project: # Project Name: greg k-h's linux 2.5 USB kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1659 -> 1.1660 # drivers/usb/storage/isd200.c 1.41 -> 1.42 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/08/12 [EMAIL PROTECTED] 1.1660 # Don't do DMA into the middle of a structure (info->drive). # Don't use I/O buffers for two different purposes simultaneously # (info->ATARegs, regs, us->iobuf). # -------------------------------------------- # diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c --- a/drivers/usb/storage/isd200.c Tue Aug 12 16:11:14 2003 +++ b/drivers/usb/storage/isd200.c Tue Aug 12 16:11:14 2003 @@ -272,8 +272,9 @@ struct isd200_info { struct inquiry_data InquiryData; - struct hd_driveid drive; + struct hd_driveid *drive; struct isd200_config ConfigData; + unsigned char *RegsBuf; unsigned char ATARegs[8]; unsigned char DeviceHead; unsigned char DeviceFlags; @@ -473,7 +474,7 @@ ata.generic.RegisterSelect = REG_COMMAND; ata.write.CommandByte = WIN_IDENTIFY; srb->sc_data_direction = SCSI_DATA_READ; - srb->request_buffer = (void *)&info->drive; + srb->request_buffer = (void *) info->drive; srb->request_bufflen = sizeof(struct hd_driveid); break; @@ -513,11 +514,12 @@ US_DEBUGP("Entering isd200_IssueATAReadRegs\n"); transferStatus = isd200_action( us, ACTION_READ_STATUS, - info->ATARegs, sizeof(info->ATARegs) ); + info->RegsBuf, sizeof(info->ATARegs) ); if (transferStatus != ISD200_TRANSPORT_GOOD) { US_DEBUGP(" Error reading ATA registers\n"); retStatus = ISD200_ERROR; } else { + memcpy(info->ATARegs, info->RegsBuf, sizeof(info->ATARegs)); US_DEBUGP(" Got ATA Register[IDE_ERROR_OFFSET] = 0x%x\n", info->ATARegs[IDE_ERROR_OFFSET]); } @@ -835,9 +837,9 @@ int detect ) { int status = ISD200_GOOD; - unsigned char *regs = us->iobuf; unsigned long endTime; struct isd200_info *info = (struct isd200_info *)us->extra; + unsigned char *regs = info->RegsBuf; int recheckAsMaster = FALSE; if ( detect ) @@ -984,6 +986,7 @@ { struct isd200_info *info = (struct isd200_info *)us->extra; int retStatus = ISD200_GOOD; + struct hd_driveid *drive = info->drive; US_DEBUGP("Entering isd200_get_inquiry_data\n"); @@ -1000,7 +1003,7 @@ /* this must be an ATA device */ /* perform an ATA Command Identify */ transferStatus = isd200_action( us, ACTION_IDENTIFY, - &info->drive, + drive, sizeof(struct hd_driveid) ); if (transferStatus != ISD200_TRANSPORT_GOOD) { /* Error issuing ATA Command Identify */ @@ -1010,35 +1013,35 @@ /* ATA Command Identify successful */ int i; __u16 *src, *dest; - ide_fix_driveid(&info->drive); + ide_fix_driveid(drive); US_DEBUGP(" Identify Data Structure:\n"); - US_DEBUGP(" config = 0x%x\n", info->drive.config); - US_DEBUGP(" cyls = 0x%x\n", info->drive.cyls); - US_DEBUGP(" heads = 0x%x\n", info->drive.heads); - US_DEBUGP(" track_bytes = 0x%x\n", info->drive.track_bytes); - US_DEBUGP(" sector_bytes = 0x%x\n", info->drive.sector_bytes); - US_DEBUGP(" sectors = 0x%x\n", info->drive.sectors); - US_DEBUGP(" serial_no[0] = 0x%x\n", info->drive.serial_no[0]); - US_DEBUGP(" buf_type = 0x%x\n", info->drive.buf_type); - US_DEBUGP(" buf_size = 0x%x\n", info->drive.buf_size); - US_DEBUGP(" ecc_bytes = 0x%x\n", info->drive.ecc_bytes); - US_DEBUGP(" fw_rev[0] = 0x%x\n", info->drive.fw_rev[0]); - US_DEBUGP(" model[0] = 0x%x\n", info->drive.model[0]); - US_DEBUGP(" max_multsect = 0x%x\n", info->drive.max_multsect); - US_DEBUGP(" dword_io = 0x%x\n", info->drive.dword_io); - US_DEBUGP(" capability = 0x%x\n", info->drive.capability); - US_DEBUGP(" tPIO = 0x%x\n", info->drive.tPIO); - US_DEBUGP(" tDMA = 0x%x\n", info->drive.tDMA); - US_DEBUGP(" field_valid = 0x%x\n", info->drive.field_valid); - US_DEBUGP(" cur_cyls = 0x%x\n", info->drive.cur_cyls); - US_DEBUGP(" cur_heads = 0x%x\n", info->drive.cur_heads); - US_DEBUGP(" cur_sectors = 0x%x\n", info->drive.cur_sectors); - US_DEBUGP(" cur_capacity = 0x%x\n", (info->drive.cur_capacity1 << 16) + info->drive.cur_capacity0 ); - US_DEBUGP(" multsect = 0x%x\n", info->drive.multsect); - US_DEBUGP(" lba_capacity = 0x%x\n", info->drive.lba_capacity); - US_DEBUGP(" command_set_1 = 0x%x\n", info->drive.command_set_1); - US_DEBUGP(" command_set_2 = 0x%x\n", info->drive.command_set_2); + US_DEBUGP(" config = 0x%x\n", drive->config); + US_DEBUGP(" cyls = 0x%x\n", drive->cyls); + US_DEBUGP(" heads = 0x%x\n", drive->heads); + US_DEBUGP(" track_bytes = 0x%x\n", drive->track_bytes); + US_DEBUGP(" sector_bytes = 0x%x\n", drive->sector_bytes); + US_DEBUGP(" sectors = 0x%x\n", drive->sectors); + US_DEBUGP(" serial_no[0] = 0x%x\n", drive->serial_no[0]); + US_DEBUGP(" buf_type = 0x%x\n", drive->buf_type); + US_DEBUGP(" buf_size = 0x%x\n", drive->buf_size); + US_DEBUGP(" ecc_bytes = 0x%x\n", drive->ecc_bytes); + US_DEBUGP(" fw_rev[0] = 0x%x\n", drive->fw_rev[0]); + US_DEBUGP(" model[0] = 0x%x\n", drive->model[0]); + US_DEBUGP(" max_multsect = 0x%x\n", drive->max_multsect); + US_DEBUGP(" dword_io = 0x%x\n", drive->dword_io); + US_DEBUGP(" capability = 0x%x\n", drive->capability); + US_DEBUGP(" tPIO = 0x%x\n", drive->tPIO); + US_DEBUGP(" tDMA = 0x%x\n", drive->tDMA); + US_DEBUGP(" field_valid = 0x%x\n", drive->field_valid); + US_DEBUGP(" cur_cyls = 0x%x\n", drive->cur_cyls); + US_DEBUGP(" cur_heads = 0x%x\n", drive->cur_heads); + US_DEBUGP(" cur_sectors = 0x%x\n", drive->cur_sectors); + US_DEBUGP(" cur_capacity = 0x%x\n", (drive->cur_capacity1 << 16) + drive->cur_capacity0 ); + US_DEBUGP(" multsect = 0x%x\n", drive->multsect); + US_DEBUGP(" lba_capacity = 0x%x\n", drive->lba_capacity); + US_DEBUGP(" command_set_1 = 0x%x\n", drive->command_set_1); + US_DEBUGP(" command_set_2 = 0x%x\n", drive->command_set_2); memset(&info->InquiryData, 0, sizeof(info->InquiryData)); @@ -1054,30 +1057,30 @@ /* The length must be at least 36 (5 + 31) */ info->InquiryData.AdditionalLength = 0x1F; - if (info->drive.command_set_1 & COMMANDSET_MEDIA_STATUS) { + if (drive->command_set_1 & COMMANDSET_MEDIA_STATUS) { /* set the removable bit */ info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE; info->DeviceFlags |= DF_REMOVABLE_MEDIA; } /* Fill in vendor identification fields */ - src = (__u16*)info->drive.model; + src = (__u16*)drive->model; dest = (__u16*)info->InquiryData.VendorId; for (i=0;i<4;i++) dest[i] = be16_to_cpu(src[i]); - src = (__u16*)(info->drive.model+8); + src = (__u16*)(drive->model+8); dest = (__u16*)info->InquiryData.ProductId; for (i=0;i<8;i++) dest[i] = be16_to_cpu(src[i]); - src = (__u16*)info->drive.fw_rev; + src = (__u16*)drive->fw_rev; dest = (__u16*)info->InquiryData.ProductRevisionLevel; for (i=0;i<2;i++) dest[i] = be16_to_cpu(src[i]); /* determine if it supports Media Status Notification */ - if (info->drive.command_set_2 & COMMANDSET_MEDIA_STATUS) { + if (drive->command_set_2 & COMMANDSET_MEDIA_STATUS) { US_DEBUGP(" Device supports Media Status Notification\n"); /* Indicate that it is enabled, even though it is not @@ -1101,11 +1104,9 @@ US_DEBUGP("Protocol changed to: %s\n", us->protocol_name); /* Free driver structure */ - if (us->extra != NULL) { - kfree(us->extra); - us->extra = NULL; - us->extra_destructor = NULL; - } + us->extra_destructor(info); + us->extra = NULL; + us->extra_destructor = NULL; } } @@ -1182,6 +1183,7 @@ union ata_cdb * ataCdb) { struct isd200_info *info = (struct isd200_info *)us->extra; + struct hd_driveid *drive = info->drive; int sendToTransport = TRUE; unsigned char sectnum, head; unsigned short cylinder; @@ -1254,12 +1256,12 @@ US_DEBUGP(" ATA OUT - SCSIOP_READ_CAPACITY\n"); - if (info->drive.capability & CAPABILITY_LBA ) { - capacity = info->drive.lba_capacity - 1; + if (drive->capability & CAPABILITY_LBA ) { + capacity = drive->lba_capacity - 1; } else { - capacity = (info->drive.heads * - info->drive.cyls * - info->drive.sectors) - 1; + capacity = (drive->heads * + drive->cyls * + drive->sectors) - 1; } readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity); readCapacityData.BytesPerBlock = cpu_to_be32(0x200); @@ -1280,16 +1282,16 @@ lba = cpu_to_be32(lba); blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8]; - if (info->drive.capability & CAPABILITY_LBA) { + if (drive->capability & CAPABILITY_LBA) { sectnum = (unsigned char)(lba); cylinder = (unsigned short)(lba>>8); head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F); } else { - sectnum = (unsigned char)((lba % info->drive.sectors) + 1); - cylinder = (unsigned short)(lba / (info->drive.sectors * - info->drive.heads)); - head = (unsigned char)((lba / info->drive.sectors) % - info->drive.heads); + sectnum = (unsigned char)((lba % drive->sectors) + 1); + cylinder = (unsigned short)(lba / (drive->sectors * + drive->heads)); + head = (unsigned char)((lba / drive->sectors) % + drive->heads); } ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; @@ -1313,14 +1315,14 @@ lba = cpu_to_be32(lba); blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8]; - if (info->drive.capability & CAPABILITY_LBA) { + if (drive->capability & CAPABILITY_LBA) { sectnum = (unsigned char)(lba); cylinder = (unsigned short)(lba>>8); head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F); } else { - sectnum = (unsigned char)((lba % info->drive.sectors) + 1); - cylinder = (unsigned short)(lba / (info->drive.sectors * info->drive.heads)); - head = (unsigned char)((lba / info->drive.sectors) % info->drive.heads); + sectnum = (unsigned char)((lba % drive->sectors) + 1); + cylinder = (unsigned short)(lba / (drive->sectors * drive->heads)); + head = (unsigned char)((lba / drive->sectors) % drive->heads); } ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; @@ -1398,6 +1400,21 @@ /************************************************************************** + * isd200_free_info + * + * Frees the driver structure. + */ +void isd200_free_info_ptrs(void *info_) +{ + struct isd200_info *info = (struct isd200_info *) info_; + + if (info) { + kfree(info->drive); + kfree(info->RegsBuf); + } +} + +/************************************************************************** * isd200_init_info * * Allocates (if necessary) and initializes the driver structure. @@ -1408,18 +1425,31 @@ int isd200_init_info(struct us_data *us) { int retStatus = ISD200_GOOD; + struct isd200_info *info; - if (!us->extra) { - us->extra = (void *) kmalloc(sizeof(struct isd200_info), GFP_KERNEL); - if (!us->extra) { - US_DEBUGP("ERROR - kmalloc failure\n"); + info = (struct isd200_info *) + kmalloc(sizeof(struct isd200_info), GFP_KERNEL); + if (!info) + retStatus = ISD200_ERROR; + else { + memset(info, 0, sizeof(struct isd200_info)); + info->drive = (struct hd_driveid *) + kmalloc(sizeof(struct hd_driveid), GFP_KERNEL); + info->RegsBuf = (unsigned char *) + kmalloc(sizeof(info->ATARegs), GFP_KERNEL); + if (!info->drive || !info->RegsBuf) { + isd200_free_info_ptrs(info); + kfree(info); retStatus = ISD200_ERROR; - } + } else + memset(info->drive, 0, sizeof(struct hd_driveid)); } if (retStatus == ISD200_GOOD) { - memset(us->extra, 0, sizeof(struct isd200_info)); - } + us->extra = info; + us->extra_destructor = isd200_free_info_ptrs; + } else + US_DEBUGP("ERROR - kmalloc failure\n"); return(retStatus); } ------------------------------------------------------- This SF.Net email sponsored by: Free pre-built ASP.NET sites including Data Reports, E-commerce, Portals, and Forums are available now. Download today and enter to win an XBOX or Visual Studio .NET. http://aspnet.click-url.com/go/psa00100003ave/direct;at.aspnet_072303_01/01 _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel