# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.5.62 -> 1.1064 # fs/nfsd/nfs3xdr.c 1.29 -> 1.32 # drivers/scsi/megaraid.c 1.34 -> 1.35 # drivers/scsi/ips.c 1.47 -> 1.48 # drivers/scsi/pci2220i.c 1.15 -> 1.16 # fs/nfsd/nfsxdr.c 1.22 -> 1.23 # drivers/scsi/eata_dma.c 1.9 -> (deleted) # drivers/scsi/aha152x.c 1.21 -> 1.22 # include/linux/raid/md_k.h 1.49 -> 1.51 # drivers/scsi/cpqfcTSinit.c 1.30 -> 1.31 # include/linux/raid/md.h 1.22 -> 1.23 # drivers/scsi/aic7xxx/aic7xxx_osm.c 1.17 -> 1.18 # net/sunrpc/svcsock.c 1.39 -> 1.40 # include/linux/nfsd/xdr4.h 1.8 -> 1.9 # drivers/scsi/53c700.c 1.24 -> 1.25 # drivers/md/raid5.c 1.57 -> 1.59 # drivers/block/cciss_scsi.c 1.8.1.3 -> 1.10 # drivers/scsi/scsi.h 1.60 -> 1.61 # drivers/md/md.c 1.135 -> 1.138 # drivers/scsi/advansys.c 1.26 -> 1.27 # drivers/scsi/cpqioctl.c 1.1 -> (deleted) # drivers/scsi/pcmcia/nsp_message.c 1.5 -> 1.6 # drivers/scsi/hosts.h 1.52 -> 1.53 # drivers/scsi/eata_dma_proc.h 1.1 -> (deleted) # drivers/scsi/nsp32.c 1.6 -> 1.7 # drivers/scsi/aacraid/linit.c 1.8 -> 1.9 # drivers/message/fusion/mptscsih.c 1.18 -> 1.19 # drivers/scsi/aic7xxx_old.c 1.42 -> 1.43 # drivers/md/linear.c 1.22 -> 1.23 # drivers/md/multipath.c 1.42 -> 1.43 # drivers/scsi/AM53C974.c 1.10 -> 1.11 # drivers/scsi/scsi_lib.c 1.68 -> 1.70 # drivers/scsi/scsi.c 1.90 -> 1.91 # drivers/scsi/aha1542.c 1.19.1.1 -> 1.21 # drivers/md/raid1.c 1.50 -> 1.52 # include/linux/sunrpc/svc.h 1.18 -> 1.19 # drivers/scsi/aic7xxx/aic79xx_osm.c 1.17.1.2 -> 1.21 # fs/nfsd/nfssvc.c 1.33 -> 1.34 # fs/nfsd/export.c 1.69 -> 1.70 # drivers/scsi/dmx3191d.c 1.9 -> 1.10 # include/linux/raid/raid1.h 1.14 -> 1.15 # drivers/scsi/ppa.c 1.17.1.1 -> 1.19 # include/linux/nfsd/nfsfh.h 1.11 -> 1.12 # drivers/scsi/pci2000.c 1.12 -> 1.13 # drivers/scsi/sym53c8xx.c 1.23 -> 1.24 # drivers/scsi/fdomain.c 1.16 -> 1.17 # drivers/scsi/eata_dma_proc.c 1.2 -> (deleted) # drivers/scsi/qlogicfc.c 1.25 -> 1.26 # Documentation/scsi/scsi_mid_low_api.txt 1.9 -> 1.10 # drivers/scsi/scsi_scan.c 1.58 -> 1.59 # drivers/scsi/Makefile 1.37 -> 1.38 # drivers/scsi/sim710.c 1.8 -> 1.10 # fs/nfsd/nfs4xdr.c 1.8 -> 1.9 # include/linux/raid/raid5.h 1.13 -> 1.14 # drivers/scsi/sym53c8xx_2/sym_malloc.c 1.1 -> 1.2 # drivers/scsi/pcmcia/aha152x_stub.c 1.11 -> 1.12 # drivers/scsi/Kconfig 1.12 -> 1.14 # drivers/scsi/3w-xxxx.c 1.22 -> 1.23 # drivers/scsi/eata_dma.h 1.3 -> (deleted) # drivers/scsi/qlogicisp.c 1.17 -> 1.18 # drivers/scsi/pcmcia/nsp_cs.c 1.15 -> 1.16 # drivers/scsi/wd7000.c 1.16.1.1 -> 1.18 # drivers/scsi/imm.c 1.16.1.1 -> 1.18 # fs/nfsctl.c 1.5 -> 1.6 # fs/nfsd/nfs4proc.c 1.6 -> 1.7 # drivers/scsi/qla1280.c 1.30 -> 1.31 # drivers/scsi/sym53c8xx_2/sym_glue.c 1.13 -> 1.15 # drivers/scsi/tmscsim.c 1.16 -> 1.17 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/02/17 torvalds@home.transmeta.com 1.1051 # Linux 2.5.62 # -------------------------------------------- # 03/02/17 jejb@raven.il.steeleye.com 1.1052 # Merge raven.il.steeleye.com:/home/jejb/BK/scsi-misc-2.5 # into raven.il.steeleye.com:/home/jejb/BK/scsi-for-linus-2.5 # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1053 # [PATCH] Bounds checking for NFSv3 readdirplus # # From Ted Phelps # # The NFSv3 readdirplus path doesn't check to see if maxcount is less # than the size of a page before it fills it up, possibly overwriting # random bits of memory. At least, it makes my Solaris NFSv3 client # work. # # The attached patch, against 2.5.58, adds this check in a way which is # consistent with the way readdir does under both NFSv2 andNFSv3. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1054 # [PATCH] Keep track of which page is the 'tail' of an NFSd reply # # NFS replies can have a 'tail' after a 'data' component # (for read, readlink, readdir). # # For nfsv2 and v3 this tail is in the same page as the head. # For nfsv4, this tail is in a separate page. # # We need to keep track of which page so that it right one # gets sent. This patch does that. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1055 # [PATCH] Fix handling of error code in NFSv4 replies # # As nfsv4 does some reply encoding while processing # requests, the code which tries to put the overall status # at the head of the reply fails. # # With this patch, we take the address for the overall # status very early so NFSv4's encoding wont confuse us. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1056 # [PATCH] Fix problem where knfsd wouldn't release filesystem on unexport. # # Problem was that the cache was being updated inplace, rather # than swapping in a new entry, so old filesystem pointers # were overwritten without being released. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1057 # [PATCH] Make kNFSd pre/post_[acm]time use struct timespec # # From Trond: # # When the nanosecond resolution on [acm]time was introduced to 2.5.x, # the knfsd GETATTR responses were converted to make use of the # nanosecond field, but the pre/post WCC attributes were not. This will # lead to a lot of unnecessary cache invalidations on the clients. # # The following trivial patch should fix up knfsd so that it stores and # encodes the full 'struct timespec' in both pre and post attribute # fields. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1058 # [PATCH] Convert fs/nfsctl.c to use C99 named initiailzers # # From Art Haas : # # This converts the file to use C99 named initializers. These change make # the file compile with fewer warnings if '-W' is added to the compile # flags, and may enhance code readability. Let me know if you think this # should be sent to Linus. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1059 # [PATCH] Fix bug in md superblock sanity checking. # # This call the super_90_load is meant to make sure that the new # superblock is consistant with a pre-exisitnig one (on rdev0)... but # rdev0 was not passed :-( # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1060 # [PATCH] linear.c fix for gcc bug # # From Andrew Morton : # # gcc-2.95.3 is getting an internal compiler error with CONFIG_LBD=y. Reorganising # the code a bit made it go away. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1061 # [PATCH] Small bug fix for multipath. # # by the nature of multipath, already be in-sync, so we should set the # in-sync flag. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1062 # [PATCH] C99 initializers for drivers/md/md.c # # From Art Haas : # # This converts md.c to use C99 initializers to improve readability and # remove warnings if '-W' is used. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1063 # [PATCH] Add name of md device to name of thread managing that device. # # This allows the thread to easily identified and signalled. # The point of signalling will appear in the next patch. # -------------------------------------------- # 03/02/17 neilb@cse.unsw.edu.au 1.1064 # [PATCH] Provide a 'safe-mode' for soft raid. # # When a raid1 or raid5 array is in 'safe-mode', then the array # is marked clean whenever there are no outstanding write requests, # and is marked dirty again before allowing any write request to # proceed. # # This means than an unclean shutdown while no write activity is happening # will NOT cause a resync to be required. However it does mean extra # updates to the superblock. # # Currently safe-mode is turned on by sending SIGKILL to the raid thread # as would happen at a normal shutdown. This should mean that the # reboot notifier is no longer needed. # # After looking more at performance issues I may make safemode be on # all the time. I will almost certainly make it on when RAID5 is degraded # as an unclean shutdown of a degraded RAID5 means data loss. # # This code was provided by Angus Sawyer # -------------------------------------------- # diff -Nru a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt --- a/Documentation/scsi/scsi_mid_low_api.txt Tue Feb 18 01:03:47 2003 +++ b/Documentation/scsi/scsi_mid_low_api.txt Tue Feb 18 01:03:47 2003 @@ -404,15 +404,15 @@ /** - * scsi_set_pci_device - place PCI device reference in host structure + * scsi_set_device - place device reference in host structure * @shost: a pointer to a scsi host instance - * @pdev: pointer to PCI device instance to assign + * @pdev: pointer to device instance to assign * * Returns nothing * * Notes: Defined in drivers/scsi/hosts.h . **/ -void scsi_set_pci_device(struct Scsi_Host * shost, struct pci_dev * pdev) +void scsi_set_device(struct Scsi_Host * shost, struct device * dev) /** diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c --- a/drivers/block/cciss_scsi.c Tue Feb 18 01:03:47 2003 +++ b/drivers/block/cciss_scsi.c Tue Feb 18 01:03:47 2003 @@ -737,7 +737,7 @@ sh->hostdata[0] = (unsigned long) hba[i]; sh->irq = hba[i]->intr; sh->unique_id = sh->irq; - scsi_set_pci_device(sh, hba[i]->pdev); + scsi_set_device(sh, &hba[i]->pdev->dev); return 1; /* Say we have 1 scsi adapter, this will be */ /* called multiple times, once for each adapter */ diff -Nru a/drivers/md/linear.c b/drivers/md/linear.c --- a/drivers/md/linear.c Tue Feb 18 01:03:47 2003 +++ b/drivers/md/linear.c Tue Feb 18 01:03:47 2003 @@ -110,9 +110,18 @@ goto out; } + /* + * This code was restructured to work around a gcc-2.95.3 internal + * compiler error. Alter it with care. + */ { - sector_t sz = md_size[mdidx(mddev)]; - unsigned round = sector_div(sz, conf->smallest->size); + sector_t sz; + unsigned round; + unsigned long base; + + sz = md_size[mdidx(mddev)]; + base = conf->smallest->size; + round = sector_div(sz, base); nb_zone = conf->nr_zones = sz + (round ? 1 : 0); } diff -Nru a/drivers/md/md.c b/drivers/md/md.c --- a/drivers/md/md.c Tue Feb 18 01:03:47 2003 +++ b/drivers/md/md.c Tue Feb 18 01:03:47 2003 @@ -83,21 +83,45 @@ static struct ctl_table_header *raid_table_header; static ctl_table raid_table[] = { - {DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min", - &sysctl_speed_limit_min, sizeof(int), 0644, NULL, &proc_dointvec}, - {DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max", - &sysctl_speed_limit_max, sizeof(int), 0644, NULL, &proc_dointvec}, - {0} + { + .ctl_name = DEV_RAID_SPEED_LIMIT_MIN, + .procname = "speed_limit_min", + .data = &sysctl_speed_limit_min, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { + .ctl_name = DEV_RAID_SPEED_LIMIT_MAX, + .procname = "speed_limit_max", + .data = &sysctl_speed_limit_max, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, + { .ctl_name = 0 } }; static ctl_table raid_dir_table[] = { - {DEV_RAID, "raid", NULL, 0, 0555, raid_table}, - {0} + { + .ctl_name = DEV_RAID, + .procname = "raid", + .maxlen = 0, + .mode = 0555, + .child = raid_table, + }, + { .ctl_name = 0 } }; static ctl_table raid_root_table[] = { - {CTL_DEV, "dev", NULL, 0, 0555, raid_dir_table}, - {0} + { + .ctl_name = CTL_DEV, + .procname = "dev", + .maxlen = 0, + .mode = 0555, + .proc_handler = raid_dir_table, + }, + { .ctl_name = 0 } }; static void md_recover_arrays(void); @@ -209,6 +233,11 @@ return down_interruptible(&mddev->reconfig_sem); } +static inline void mddev_lock_uninterruptible(mddev_t * mddev) +{ + down(&mddev->reconfig_sem); +} + static inline int mddev_trylock(mddev_t * mddev) { return down_trylock(&mddev->reconfig_sem); @@ -1050,8 +1079,8 @@ if (!mddev->persistent) return; - printk(KERN_INFO "md: updating md%d RAID superblock on device\n", - mdidx(mddev)); + printk(KERN_INFO "md: updating md%d RAID superblock on device (in sync %d)\n", + mdidx(mddev),mddev->in_sync); err = 0; ITERATE_RDEV(mddev,rdev,tmp) { @@ -1490,6 +1519,8 @@ mddev->pers = NULL; return -EINVAL; } + atomic_set(&mddev->writes_pending,0); + mddev->safemode = 0; if (mddev->pers->sync_request) mddev->in_sync = 0; else @@ -1521,6 +1552,7 @@ if (!mddev->ro) goto out; + mddev->safemode = 0; mddev->in_sync = 0; md_update_sb(mddev); mddev->ro = 0; @@ -1925,7 +1957,7 @@ if (!list_empty(&mddev->disks)) { mdk_rdev_t *rdev0 = list_entry(mddev->disks.next, mdk_rdev_t, same_set); - int err = super_90_load(rdev, NULL); + int err = super_90_load(rdev, rdev0); if (err < 0) { printk(KERN_WARNING "md: %s has different UUID to %s\n", bdev_partition_name(rdev->bdev), bdev_partition_name(rdev0->bdev)); @@ -2794,6 +2826,48 @@ } +void md_write_start(mddev_t *mddev) +{ + if (mddev->safemode && !atomic_read(&mddev->writes_pending)) { + mddev_lock_uninterruptible(mddev); + atomic_inc(&mddev->writes_pending); + if (mddev->in_sync) { + mddev->in_sync = 0; + md_update_sb(mddev); + } + mddev_unlock(mddev); + } else + atomic_inc(&mddev->writes_pending); +} + +void md_write_end(mddev_t *mddev, mdk_thread_t *thread) +{ + if (atomic_dec_and_test(&mddev->writes_pending) && mddev->safemode) + md_wakeup_thread(thread); +} +static inline void md_enter_safemode(mddev_t *mddev) +{ + + mddev_lock_uninterruptible(mddev); + if (mddev->safemode && !atomic_read(&mddev->writes_pending) && !mddev->in_sync && !mddev->recovery_running) { + mddev->in_sync = 1; + md_update_sb(mddev); + } + mddev_unlock(mddev); +} + +void md_handle_safemode(mddev_t *mddev) +{ + if (signal_pending(current)) { + printk(KERN_INFO "md: md%d in safe mode\n",mdidx(mddev)); + mddev->safemode= 1; + flush_curr_signals(); + } + if (mddev->safemode) + md_enter_safemode(mddev); +} + + DECLARE_WAIT_QUEUE_HEAD(resync_wait); #define SYNC_MARKS 10 @@ -2971,6 +3045,8 @@ mddev->recovery_running = 0; if (mddev->recovery_running == 0) mddev->recovery_cp = MaxSector; + if (mddev->safemode) + md_enter_safemode(mddev); md_recover_arrays(); } @@ -3246,6 +3322,9 @@ EXPORT_SYMBOL(md_error); EXPORT_SYMBOL(md_sync_acct); EXPORT_SYMBOL(md_done_sync); +EXPORT_SYMBOL(md_write_start); +EXPORT_SYMBOL(md_write_end); +EXPORT_SYMBOL(md_handle_safemode); EXPORT_SYMBOL(md_register_thread); EXPORT_SYMBOL(md_unregister_thread); EXPORT_SYMBOL(md_wakeup_thread); diff -Nru a/drivers/md/multipath.c b/drivers/md/multipath.c --- a/drivers/md/multipath.c Tue Feb 18 01:03:47 2003 +++ b/drivers/md/multipath.c Tue Feb 18 01:03:47 2003 @@ -283,6 +283,7 @@ p->rdev = rdev; conf->working_disks++; rdev->raid_disk = path; + rdev->in_sync = 1; found = 1; } spin_unlock_irq(&conf->device_lock); diff -Nru a/drivers/md/raid1.c b/drivers/md/raid1.c --- a/drivers/md/raid1.c Tue Feb 18 01:03:47 2003 +++ b/drivers/md/raid1.c Tue Feb 18 01:03:47 2003 @@ -319,8 +319,10 @@ * Let's see if all mirrored write operations have finished * already. */ - if (atomic_dec_and_test(&r1_bio->remaining)) + if (atomic_dec_and_test(&r1_bio->remaining)) { + md_write_end(r1_bio->mddev,conf->thread); raid_end_bio_io(r1_bio, uptodate); + } } atomic_dec(&conf->mirrors[mirror].rdev->nr_pending); return 0; @@ -540,6 +542,7 @@ * If all mirrors are non-operational * then return an IO error: */ + md_write_end(mddev,conf->thread); raid_end_bio_io(r1_bio, 0); return 0; } @@ -555,6 +558,8 @@ * do end_request by hand if all requests finish until we had a * chance to set up the semaphore correctly ... lots of races). */ + + md_write_start(mddev); for (i=disks; i--; ) { struct bio *mbio; mbio = r1_bio->write_bios[i]; @@ -902,10 +907,11 @@ struct bio *bio; unsigned long flags; mddev_t *mddev; - conf_t *conf; + conf_t *conf = data; mdk_rdev_t *rdev; - + md_handle_safemode(conf->mddev); + for (;;) { spin_lock_irqsave(&retry_list_lock, flags); if (list_empty(head)) @@ -1184,9 +1190,9 @@ { - const char * name = "raid1d"; + snprintf(conf->thread_name,MD_THREAD_NAME_MAX,"raid1d_md%d",mdidx(mddev)); - conf->thread = md_register_thread(raid1d, conf, name); + conf->thread = md_register_thread(raid1d, conf, conf->thread_name); if (!conf->thread) { printk(THREAD_ERROR, mdidx(mddev)); goto out_free_conf; diff -Nru a/drivers/md/raid5.c b/drivers/md/raid5.c --- a/drivers/md/raid5.c Tue Feb 18 01:03:47 2003 +++ b/drivers/md/raid5.c Tue Feb 18 01:03:47 2003 @@ -913,6 +913,7 @@ struct bio *nextbi = bi->bi_next; clear_bit(BIO_UPTODATE, &bi->bi_flags); if (--bi->bi_phys_segments == 0) { + md_write_end(conf->mddev, conf->thread); bi->bi_next = return_bi; return_bi = bi; } @@ -963,16 +964,19 @@ /* We can return any write requests */ struct bio *wbi, *wbi2; PRINTK("Return write for disc %d\n", i); + spin_lock_irq(&conf->device_lock); wbi = dev->written; dev->written = NULL; while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) { wbi2 = wbi->bi_next; if (--wbi->bi_phys_segments == 0) { + md_write_end(conf->mddev, conf->thread); wbi->bi_next = return_bi; return_bi = wbi; } wbi = wbi2; } + spin_unlock_irq(&conf->device_lock); } } } @@ -1275,6 +1279,8 @@ bi->bi_next = NULL; bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ + if ( bio_data_dir(bi) == WRITE ) + md_write_start(mddev); for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { new_sector = raid5_compute_sector(logical_sector, @@ -1297,6 +1303,8 @@ if (--bi->bi_phys_segments == 0) { int bytes = bi->bi_size; + if ( bio_data_dir(bi) == WRITE ) + md_write_end(mddev,conf->thread); bi->bi_size = 0; bi->bi_end_io(bi, bytes, 0); } @@ -1357,6 +1365,7 @@ PRINTK("+++ raid5d active\n"); + md_handle_safemode(mddev); handled = 0; spin_lock_irq(&conf->device_lock); while (1) { @@ -1477,9 +1486,9 @@ } { - const char * name = "raid5d"; + snprintf(conf->thread_name,MD_THREAD_NAME_MAX,"raid5d_md%d",mdidx(mddev)); - conf->thread = md_register_thread(raid5d, conf, name); + conf->thread = md_register_thread(raid5d, conf, conf->thread_name); if (!conf->thread) { printk(KERN_ERR "raid5: couldn't allocate thread for md%d\n", mdidx(mddev)); goto abort; diff -Nru a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c --- a/drivers/message/fusion/mptscsih.c Tue Feb 18 01:03:47 2003 +++ b/drivers/message/fusion/mptscsih.c Tue Feb 18 01:03:47 2003 @@ -1769,7 +1769,7 @@ /* Set the pci device pointer in Scsi_Host structure. */ - scsi_set_pci_device(sh, this->pcidev); + scsi_set_device(sh, &this->pcidev->dev); spin_unlock_irqrestore(&this->FreeQlock, flags); diff -Nru a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c --- a/drivers/scsi/3w-xxxx.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/3w-xxxx.c Tue Feb 18 01:03:48 2003 @@ -960,7 +960,9 @@ host->max_sectors = TW_MAX_SECTORS; #endif -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_set_device(host, &tw_pci_dev->dev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) scsi_set_pci_device(host, tw_pci_dev); #endif diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c --- a/drivers/scsi/53c700.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/53c700.c Tue Feb 18 01:03:47 2003 @@ -1769,7 +1769,7 @@ NCR_700_set_depth(SCp->device, NCR_700_get_depth(SCp->device) + 1); /* begin the command here */ - /* no need to check for NULL, test for command_slot_cound above + /* no need to check for NULL, test for command_slot_count above * ensures a slot is free */ slot = find_empty_slot(hostdata); diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c --- a/drivers/scsi/AM53C974.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/AM53C974.c Tue Feb 18 01:03:47 2003 @@ -680,7 +680,7 @@ printk(KERN_WARNING "AM53C974: Unable to register host, aborting.\n"); return 0; } - scsi_set_pci_device(instance, pdev); + scsi_set_device(instance, &pdev->dev); hostdata = (struct AM53C974_hostdata *) instance->hostdata; instance->base = 0; instance->io_port = pci_resource_start(pdev, 0); diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig --- a/drivers/scsi/Kconfig Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/Kconfig Tue Feb 18 01:03:47 2003 @@ -471,10 +471,6 @@ SCSI-HOWTO, available from . - Note that there is also another driver for the same hardware - available: "EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, - Alphatronix) support". You should say Y to only one of them. - If you want to compile this as a module ( = code which can be inserted in and removed from the running kernel whenever you want), say M here and read . The module @@ -512,24 +508,6 @@ by the driver for each probed SCSI device is reported at boot time. This is equivalent to the "eata=mq:8" boot option. -config SCSI_EATA_DMA - tristate "EATA-DMA [Obsolete] (DPT, NEC, AT&T, SNI, AST, Olivetti, Alphatronix) support" - depends on SCSI - ---help--- - This is support for the EATA-DMA protocol compliant SCSI Host - Adapters like the SmartCache III/IV, SmartRAID controller families - and the DPT PM2011B and PM2012B controllers. - - Note that this driver is obsolete; if you have one of the above - SCSI Host Adapters, you should normally say N here and Y to "EATA - ISA/EISA/PCI support", below. Please read the SCSI-HOWTO, available - from . - - This driver is also available as a module ( = code which can be - inserted in and removed from the running kernel whenever you want). - The module will be called eata_dma. If you want to compile it as - a module, say M here and read . - config SCSI_EATA_PIO tristate "EATA-PIO (old DPT PM2001, PM2012A) support" depends on SCSI @@ -1728,6 +1706,13 @@ Y to this question. If you're in doubt about whether you have one, see the picture at . + +config SCSI_PC980155 + tristate "NEC PC-9801-55 SCSI support" + depends on X86_PC9800 && SCSI + help + If you have the NEC PC-9801-55 SCSI interface card or compatibles + for NEC PC-9801/PC-9821, say Y. # bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI # bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI diff -Nru a/drivers/scsi/Makefile b/drivers/scsi/Makefile --- a/drivers/scsi/Makefile Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/Makefile Tue Feb 18 01:03:47 2003 @@ -82,7 +82,6 @@ obj-$(CONFIG_SCSI_SYM53C8XX) += sym53c8xx.o obj-$(CONFIG_SCSI_NCR53C8XX) += ncr53c8xx.o obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o -obj-$(CONFIG_SCSI_EATA_DMA) += eata_dma.o obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o obj-$(CONFIG_SCSI_7000FASST) += wd7000.o obj-$(CONFIG_SCSI_MCA_53C9X) += NCR53C9x.o mca_53c9x.o diff -Nru a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c --- a/drivers/scsi/aacraid/linit.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/aacraid/linit.c Tue Feb 18 01:03:47 2003 @@ -217,7 +217,7 @@ host_ptr->irq = dev->irq; /* Adapter IRQ number */ /* host_ptr->base = ( char * )(dev->resource[0].start & ~0xff); */ host_ptr->base = dev->resource[0].start; - scsi_set_pci_device(host_ptr, dev); + scsi_set_device(host_ptr, &dev->dev); dprintk((KERN_DEBUG "Device base address = 0x%lx [0x%lx].\n", host_ptr->base, dev->resource[0].start)); dprintk((KERN_DEBUG "Device irq = 0x%x.\n", dev->irq)); /* diff -Nru a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c --- a/drivers/scsi/advansys.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/advansys.c Tue Feb 18 01:03:47 2003 @@ -4791,9 +4791,8 @@ if (shp == NULL) { continue; } -#ifdef CONFIG_PCI - scsi_set_pci_device(shp, pci_devp); -#endif + + scsi_set_device(shp, &pci_devp->dev); /* Save a pointer to the Scsi_host of each board found. */ asc_host[asc_board_count++] = shp; diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c --- a/drivers/scsi/aha152x.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/aha152x.c Tue Feb 18 01:03:47 2003 @@ -306,9 +306,9 @@ #define ERR_LEAD KERN_ERR LEAD #define DEBUG_LEAD KERN_DEBUG LEAD #define CMDINFO(cmd) \ - (cmd) ? ((cmd)->host->host_no) : -1, \ - (cmd) ? ((cmd)->target & 0x0f) : -1, \ - (cmd) ? ((cmd)->lun & 0x07) : -1 + (cmd) ? ((cmd)->device->host->host_no) : -1, \ + (cmd) ? ((cmd)->device->id & 0x0f) : -1, \ + (cmd) ? ((cmd)->device->lun & 0x07) : -1 #define DELAY_DEFAULT 1000 @@ -583,8 +583,8 @@ #define DATA_LEN (HOSTDATA(shpnt)->data_len) -#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->target]) -#define SYNCNEG (HOSTDATA(shpnt)->syncneg[CURRENT_SC->target]) +#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id]) +#define SYNCNEG (HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id]) #define DELAY (HOSTDATA(shpnt)->delay) #define EXT_TRANS (HOSTDATA(shpnt)->ext_trans) @@ -771,7 +771,7 @@ Scsi_Cmnd *ptr, *prev; for (ptr = *SC, prev = NULL; - ptr && ((ptr->target != target) || (ptr->lun != lun)); + ptr && ((ptr->device->id != target) || (ptr->device->lun != lun)); prev = ptr, ptr = SCNEXT(ptr)) ; @@ -1476,7 +1476,7 @@ */ int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct semaphore *sem, int phase, Scsi_Cmnd *done_SC, void (*done)(Scsi_Cmnd *)) { - struct Scsi_Host *shpnt = SCpnt->host; + struct Scsi_Host *shpnt = SCpnt->device->host; unsigned long flags; #if defined(AHA152X_DEBUG) @@ -1589,7 +1589,7 @@ */ int aha152x_abort(Scsi_Cmnd *SCpnt) { - struct Scsi_Host *shpnt = SCpnt->host; + struct Scsi_Host *shpnt = SCpnt->device->host; Scsi_Cmnd *ptr; unsigned long flags; @@ -1641,7 +1641,7 @@ { Scsi_Cmnd *SCp = (Scsi_Cmnd *)p; struct semaphore *sem = SCSEM(SCp); - struct Scsi_Host *shpnt = SCp->host; + struct Scsi_Host *shpnt = SCp->device->host; /* remove command from issue queue */ if(remove_SC(&ISSUE_SC, SCp)) { @@ -1663,10 +1663,11 @@ */ int aha152x_device_reset(Scsi_Cmnd * SCpnt) { - struct Scsi_Host *shpnt = SCpnt->host; + struct Scsi_Host *shpnt = SCpnt->device->host; DECLARE_MUTEX_LOCKED(sem); struct timer_list timer; - Scsi_Cmnd cmnd; + Scsi_Cmnd *cmd; + int ret; #if defined(AHA152X_DEBUG) if(HOSTDATA(shpnt)->debug & debug_eh) { @@ -1680,31 +1681,42 @@ return FAILED; } - cmnd.cmd_len = 0; - cmnd.host = SCpnt->host; - cmnd.target = SCpnt->target; - cmnd.lun = SCpnt->lun; - cmnd.use_sg = 0; - cmnd.request_buffer = 0; - cmnd.request_bufflen = 0; + spin_unlock_irq(shpnt->host_lock); + cmd = scsi_get_command(SCpnt->device, GFP_ATOMIC); + if (!cmd) { + spin_lock_irq(shpnt->host_lock); + return FAILED; + } + + cmd->cmd_len = 0; + cmd->device->host = SCpnt->device->host; + cmd->device->id = SCpnt->device->id; + cmd->device->lun = SCpnt->device->lun; + cmd->use_sg = 0; + cmd->request_buffer = 0; + cmd->request_bufflen = 0; init_timer(&timer); - timer.data = (unsigned long) &cmnd; + timer.data = (unsigned long) cmd; timer.expires = jiffies + 100*HZ; /* 10s */ timer.function = (void (*)(unsigned long)) timer_expired; - aha152x_internal_queue(&cmnd, &sem, resetting, 0, internal_done); + aha152x_internal_queue(cmd, &sem, resetting, 0, internal_done); add_timer(&timer); down(&sem); del_timer(&timer); - if(cmnd.SCp.phase & resetted) { - return SUCCESS; + if(cmd->SCp.phase & resetted) { + ret = SUCCESS; } else { - return FAILED; + ret = FAILED; } + + scsi_put_command(cmd); + spin_lock_irq(shpnt->host_lock); + return ret; } void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs) @@ -1738,7 +1750,7 @@ */ int aha152x_bus_reset(Scsi_Cmnd *SCpnt) { - struct Scsi_Host *shpnt = SCpnt->host; + struct Scsi_Host *shpnt = SCpnt->device->host; unsigned long flags; #if defined(AHA152X_DEBUG) @@ -1822,7 +1834,7 @@ aha152x_bus_reset(SCpnt); DPRINTK(debug_eh, DEBUG_LEAD "resetting ports\n", CMDINFO(SCpnt)); - reset_ports(SCpnt->host); + reset_ports(SCpnt->device->host); return SUCCESS; } @@ -2052,9 +2064,9 @@ cmnd->cmnd[4] = sizeof(ptr->sense_buffer); cmnd->cmnd[5] = 0; cmnd->cmd_len = 6; - cmnd->host = ptr->host; - cmnd->target = ptr->target; - cmnd->lun = ptr->lun; + cmnd->device->host = ptr->device->host; + cmnd->device->id = ptr->device->id; + cmnd->device->lun = ptr->device->lun; cmnd->use_sg = 0; cmnd->request_buffer = ptr->sense_buffer; cmnd->request_bufflen = sizeof(ptr->sense_buffer); @@ -2113,7 +2125,7 @@ /* clear selection timeout */ SETPORT(SSTAT1, SELTO); - SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->target); + SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->device->id); SETPORT(SXFRCTL1, (PARITY ? ENSPCHK : 0 ) | ENSTIMER); SETPORT(SCSISEQ, ENSELO | ENAUTOATNO | (DISCONNECTED_SC ? ENRESELI : 0)); } else { @@ -2152,7 +2164,7 @@ SETPORT(SSTAT0, CLRSELDO); - ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->lun)); + ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun)); if (CURRENT_SC->SCp.phase & aborting) { ADDMSGO(ABORT); @@ -2472,7 +2484,7 @@ { if(MSGOLEN==0) { if((CURRENT_SC->SCp.phase & syncneg) && SYNCNEG==2 && SYNCRATE==0) { - ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->lun)); + ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun)); } else { printk(INFO_LEAD "unexpected MESSAGE OUT phase; rejecting\n", CMDINFO(CURRENT_SC)); ADDMSGO(MESSAGE_REJECT); @@ -3376,7 +3388,7 @@ static void show_command(Scsi_Cmnd *ptr) { printk(KERN_DEBUG "0x%08x: target=%d; lun=%d; cmnd=(", - (unsigned int) ptr, ptr->target, ptr->lun); + (unsigned int) ptr, ptr->device->id, ptr->device->lun); print_command(ptr->cmnd); @@ -3441,7 +3453,7 @@ int i; SPRINTF("0x%08x: target=%d; lun=%d; cmnd=( ", - (unsigned int) ptr, ptr->target, ptr->lun); + (unsigned int) ptr, ptr->device->id, ptr->device->lun); for (i = 0; i < COMMAND_SIZE(ptr->cmnd[0]); i++) SPRINTF("0x%02x ", ptr->cmnd[i]); diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c --- a/drivers/scsi/aic7xxx/aic79xx_osm.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c Tue Feb 18 01:03:47 2003 @@ -2381,7 +2381,9 @@ ahd_set_name(ahd, new_name); } host->unique_id = ahd->unit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_set_device(host, &ahd->dev_softc->dev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) scsi_set_pci_device(host, ahd->dev_softc); #endif ahd_linux_initialize_scsi_bus(ahd); @@ -4268,6 +4270,7 @@ */ hscb->control = 0; hscb->scsiid = BUILD_SCSIID(ahd, cmd); + hscb->lun = cmd->device->lun; scb->hscb->task_management = 0; mask = SCB_GET_TARGET_MASK(ahd, scb); diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c Tue Feb 18 01:03:47 2003 @@ -1861,7 +1861,9 @@ ahc_set_name(ahc, new_name); } host->unique_id = ahc->unit; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) + scsi_set_device(host, &ahc->dev_softc->dev); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) scsi_set_pci_device(host, ahc->dev_softc); #endif ahc_linux_initialize_scsi_bus(ahc); diff -Nru a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c --- a/drivers/scsi/aic7xxx_old.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/aic7xxx_old.c Tue Feb 18 01:03:47 2003 @@ -8450,7 +8450,7 @@ } p->host_no = host->host_no; } - scsi_set_pci_device(host, p->pdev); + scsi_set_device(host, &p->pdev->dev); return (p); } diff -Nru a/drivers/scsi/cpqfcTSinit.c b/drivers/scsi/cpqfcTSinit.c --- a/drivers/scsi/cpqfcTSinit.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/cpqfcTSinit.c Tue Feb 18 01:03:47 2003 @@ -337,7 +337,7 @@ DEBUG_PCI(printk(" PciDev->baseaddress[3]= %lx\n", PciDev->resource[3].start)); - scsi_set_pci_device(HostAdapter, PciDev); + scsi_set_device(HostAdapter, &PciDev->dev); HostAdapter->irq = PciDev->irq; // copy for Scsi layers // HP Tachlite uses two (255-byte) ranges of Port I/O (lower & upper), diff -Nru a/drivers/scsi/cpqioctl.c b/drivers/scsi/cpqioctl.c --- a/drivers/scsi/cpqioctl.c Tue Feb 18 01:03:47 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,76 +0,0 @@ -// Test program for CPQFCTS ioctl calls -// build with: -// gcc -o cpqioctl cpqioctl.c -// ld -o cpqioctl /lib/crt0.o cpqioctl.o -lc - -#include -#include -#include -#include -#include -#include -#include "../../include/scsi/scsi.h" -#include "cpqfcTSioctl.h" - -typedef struct scsi_fctargaddress { - unsigned long host_port_id; - unsigned char host_wwn[8]; -} Scsi_FCTargAddress; - -int main(int argc, char **argv) { - - int fd, i; - Scsi_FCTargAddress targ; - int uselect=0; - - - - if ( argc < 2 ) { - printf("usage: cpqioctl \n"); - exit(1); - } - - if ( (fd = open(argv[1], O_RDONLY)) == -1) { - perror("open"); - exit(1); - } - - if ( ioctl(fd, SCSI_IOCTL_FC_TARGET_ADDRESS, &targ) ) { - perror("ioctl"); - exit(1); - } - - - printf("portid: %08x. wwn: ", targ.host_port_id); - - for (i=0;i<8;i++) printf(" %02x", targ.host_wwn[i]); - printf("\n"); - - while( uselect != 27 ) // not ESC key - { - printf("\n IOCTL \n"); - printf( "1. Get PCI info\n"); - printf( "2. Send Passthru\n"); - printf( " ==> "); - scanf("%c", &uselect); - - switch( uselect ) - { - case '1': - { - cciss_pci_info_struct pciinfo; - - if( ioctl( fd, CCPQFCTS_GETPCIINFO ,&pciinfo )) - perror("ioctl"); - else - printf( "\nPCI bus %d, dev_fn %d, board_id %Xh\n", - pciinfo.bus, pciinfo.dev_fn, pciinfo.board_id); - } - - } - } - - - close(fd); - return 0; -} diff -Nru a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c --- a/drivers/scsi/dmx3191d.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/dmx3191d.c Tue Feb 18 01:03:47 2003 @@ -86,7 +86,7 @@ release_region(port, DMX3191D_REGION); continue; } - scsi_set_pci_device(instance, pdev); + scsi_set_device(instance, &pdev->dev); instance->io_port = port; instance->irq = pdev->irq; NCR5380_init(instance, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); diff -Nru a/drivers/scsi/eata_dma.c b/drivers/scsi/eata_dma.c --- a/drivers/scsi/eata_dma.c Tue Feb 18 01:03:47 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,1572 +0,0 @@ -/************************************************************ - * * - * Linux EATA SCSI driver * - * * - * based on the CAM document CAM/89-004 rev. 2.0c, * - * DPT's driver kit, some internal documents and source, * - * and several other Linux scsi drivers and kernel docs. * - * * - * The driver currently: * - * -supports all ISA based EATA-DMA boards * - * like PM2011, PM2021, PM2041, PM3021 * - * -supports all EISA based EATA-DMA boards * - * like PM2012B, PM2022, PM2122, PM2322, PM2042, * - * PM3122, PM3222, PM3332 * - * -supports all PCI based EATA-DMA boards * - * like PM2024, PM2124, PM2044, PM2144, PM3224, * - * PM3334 * - * -supports the Wide, Ultra Wide and Differential * - * versions of the boards * - * -supports multiple HBAs with & without IRQ sharing * - * -supports all SCSI channels on multi channel boards * - * -supports ix86 and MIPS, untested on ALPHA * - * -needs identical IDs on all channels of a HBA * - * -can be loaded as module * - * -displays statistical and hardware information * - * in /proc/scsi/eata_dma * - * -provides rudimentary latency measurement * - * possibilities via /proc/scsi/eata_dma/ * - * * - * (c)1993-96 Michael Neuffer * - * mike@i-Connect.Net * - * neuffer@mail.uni-mainz.de * - * * - * 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 the Free Software * - * Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be * - * useful, but WITHOUT ANY WARRANTY; without even the * - * implied warranty of MERCHANTABILITY or FITNESS FOR A * - * PARTICULAR PURPOSE. See the GNU General Public License * - * for more details. * - * * - * You should have received a copy of the GNU General * - * Public License along with this kernel; if not, write to * - * the Free Software Foundation, Inc., 675 Mass Ave, * - * Cambridge, MA 02139, USA. * - * * - * I have to thank DPT for their excellent support. I took * - * me almost a year and a stopover at their HQ, on my first * - * trip to the USA, to get it, but since then they've been * - * very helpful and tried to give me all the infos and * - * support I need. * - * * - * Thanks also to Simon Shapiro, Greg Hosler and Mike * - * Jagdis who did a lot of testing and found quite a number * - * of bugs during the development. * - ************************************************************ - * last change: 96/10/21 OS: Linux 2.0.23 * - ************************************************************/ - -/* Look in eata_dma.h for configuration and revision information */ - -#error Please convert me to Documentation/DMA-mapping.txt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __mips__ -#include -#include -#endif -#include -#include "scsi.h" -#include "hosts.h" -#include "eata_dma.h" -#include "eata_dma_proc.h" - -#include -#include /* for CONFIG_PCI */ - -static u32 ISAbases[] = -{0x1F0, 0x170, 0x330, 0x230}; -static unchar EISAbases[] = -{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; -static uint registered_HBAs = 0; -static struct Scsi_Host *last_HBA = NULL; -static struct Scsi_Host *first_HBA = NULL; -static unchar reg_IRQ[] = -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static unchar reg_IRQL[] = -{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -static struct eata_sp *status = 0; /* Statuspacket array */ -static void *dma_scratch = 0; - -static struct eata_register *fake_int_base; -static int fake_int_result; -static int fake_int_happened; - -static ulong int_counter = 0; -static ulong queue_counter = 0; - -void eata_fake_int_handler(s32 irq, void *dev_id, struct pt_regs * regs) -{ - fake_int_result = inb((ulong)fake_int_base + HA_RSTATUS); - fake_int_happened = TRUE; - DBG(DBG_INTR3, printk("eata_fake_int_handler called irq%d base %p" - " res %#x\n", irq, fake_int_base, fake_int_result)); - return; -} - -#include "eata_dma_proc.c" - -#ifdef MODULE -int eata_release(struct Scsi_Host *sh) -{ - uint i; - if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL); - else reg_IRQ[sh->irq]--; - - kfree((void *)status); - kfree((void *)dma_scratch - 4); - for (i = 0; i < sh->can_queue; i++){ /* Free all SG arrays */ - if(SD(sh)->ccb[i].sg_list != NULL) - kfree((void *) SD(sh)->ccb[i].sg_list); - } - - if (SD(sh)->channel == 0) { - if (sh->dma_channel != BUSMASTER) free_dma(sh->dma_channel); - if (sh->io_port && sh->n_io_port) - release_region(sh->io_port, sh->n_io_port); - } - return(TRUE); -} -#endif - - -inline void eata_latency_in(struct eata_ccb *cp, hostdata *hd) -{ - uint time; - time = jiffies - cp->timestamp; - if(hd->all_lat[1] > time) - hd->all_lat[1] = time; - if(hd->all_lat[2] < time) - hd->all_lat[2] = time; - hd->all_lat[3] += time; - hd->all_lat[0]++; - if((cp->rw_latency) == WRITE) { /* was WRITE */ - if(hd->writes_lat[cp->sizeindex][1] > time) - hd->writes_lat[cp->sizeindex][1] = time; - if(hd->writes_lat[cp->sizeindex][2] < time) - hd->writes_lat[cp->sizeindex][2] = time; - hd->writes_lat[cp->sizeindex][3] += time; - hd->writes_lat[cp->sizeindex][0]++; - } else if((cp->rw_latency) == READ) { - if(hd->reads_lat[cp->sizeindex][1] > time) - hd->reads_lat[cp->sizeindex][1] = time; - if(hd->reads_lat[cp->sizeindex][2] < time) - hd->reads_lat[cp->sizeindex][2] = time; - hd->reads_lat[cp->sizeindex][3] += time; - hd->reads_lat[cp->sizeindex][0]++; - } -} - -inline void eata_latency_out(struct eata_ccb *cp, Scsi_Cmnd *cmd) -{ - int x, z; - short *sho; - long *lon; - x = 0; /* just to keep GCC quiet */ - cp->timestamp = jiffies; /* For latency measurements */ - switch(cmd->cmnd[0]) { - case WRITE_6: - x = cmd->cmnd[4]/2; - cp->rw_latency = WRITE; - break; - case READ_6: - x = cmd->cmnd[4]/2; - cp->rw_latency = READ; - break; - case WRITE_10: - sho = (short *) &cmd->cmnd[7]; - x = ntohs(*sho)/2; - cp->rw_latency = WRITE; - break; - case READ_10: - sho = (short *) &cmd->cmnd[7]; - x = ntohs(*sho)/2; - cp->rw_latency = READ; - break; - case WRITE_12: - lon = (long *) &cmd->cmnd[6]; - x = ntohl(*lon)/2; - cp->rw_latency = WRITE; - break; - case READ_12: - lon = (long *) &cmd->cmnd[6]; - x = ntohl(*lon)/2; - cp->rw_latency = READ; - break; - default: - cp->rw_latency = OTHER; - break; - } - if (cmd->cmnd[0] == WRITE_6 || cmd->cmnd[0] == WRITE_10 || - cmd->cmnd[0] == WRITE_12 || cmd->cmnd[0] == READ_6 || - cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == READ_12) { - for(z = 0; (x > (1 << z)) && (z <= 11); z++) - /* nothing */; - cp->sizeindex = z; - } -} - -void eata_int_handler(int, void *, struct pt_regs *); - -void do_eata_int_handler(int irq, void *dev_id, struct pt_regs * regs) -{ - unsigned long flags; - struct Scsi_Host *dev = dev_id; - - spin_lock_irqsave(dev->host_lock, flags); - eata_int_handler(irq, dev_id, regs); - spin_unlock_irqrestore(dev->host_lock, flags); -} - -void eata_int_handler(int irq, void *dev_id, struct pt_regs * regs) -{ - uint i, result = 0; - uint hba_stat, scsi_stat, eata_stat; - Scsi_Cmnd *cmd; - struct eata_ccb *ccb; - struct eata_sp *sp; - uint base; - uint x; - struct Scsi_Host *sh; - - for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { - if (sh->irq != irq) - continue; - - while(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { - - int_counter++; - - sp = &SD(sh)->sp; -#ifdef __mips__ - sys_cacheflush(sp, sizeof(struct eata_sp), 2); -#endif - ccb = sp->ccb; - - if(ccb == NULL) { - eata_stat = inb((uint)sh->base + HA_RSTATUS); - printk("eata_dma: int_handler, Spurious IRQ %d " - "received. CCB pointer not set.\n", irq); - break; - } - - cmd = ccb->cmd; - base = (uint) cmd->device->host->base; - hba_stat = sp->hba_stat; - - scsi_stat = (sp->scsi_stat >> 1) & 0x1f; - - if (sp->EOC == FALSE) { - eata_stat = inb(base + HA_RSTATUS); - printk(KERN_WARNING "eata_dma: int_handler, board: %x cmd %lx " - "returned unfinished.\n" - "EATA: %x HBA: %x SCSI: %x spadr %lx spadrirq %lx, " - "irq%d\n", base, (long)ccb, eata_stat, hba_stat, - scsi_stat,(long)&status, (long)&status[irq], irq); - cmd->result = DID_ERROR << 16; - ccb->status = FREE; - cmd->scsi_done(cmd); - break; - } - - sp->EOC = FALSE; /* Clean out this flag */ - - if (ccb->status == LOCKED || ccb->status == RESET) { - printk("eata_dma: int_handler, reseted command pid %ld returned" - "\n", cmd->pid); - DBG(DBG_INTR && DBG_DELAY, DELAY(1)); - } - - eata_stat = inb(base + HA_RSTATUS); - DBG(DBG_INTR, printk("IRQ %d received, base %#.4x, pid %ld, " - "target: %x, lun: %x, ea_s: %#.2x, hba_s: " - "%#.2x \n", irq, base, cmd->pid, cmd->device->id, - cmd->device->lun, eata_stat, hba_stat)); - - switch (hba_stat) { - case HA_NO_ERROR: /* NO Error */ - if(HD(cmd)->do_latency == TRUE && ccb->timestamp) - eata_latency_in(ccb, HD(cmd)); - result = DID_OK << 16; - break; - case HA_ERR_SEL_TO: /* Selection Timeout */ - case HA_ERR_CMD_TO: /* Command Timeout */ - result = DID_TIME_OUT << 16; - break; - case HA_BUS_RESET: /* SCSI Bus Reset Received */ - result = DID_RESET << 16; - DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: BUS RESET " - "received on cmd %ld\n", - HD(cmd)->HBA_number, cmd->pid)); - break; - case HA_INIT_POWERUP: /* Initial Controller Power-up */ - if (cmd->device->type != TYPE_TAPE) - result = DID_BUS_BUSY << 16; - else - result = DID_ERROR << 16; - - for (i = 0; i < MAXTARGET; i++) - DBG(DBG_STATUS, printk(KERN_DEBUG "scsi%d: cmd pid %ld " - "returned with INIT_POWERUP\n", - HD(cmd)->HBA_number, cmd->pid)); - break; - case HA_CP_ABORT_NA: - case HA_CP_ABORTED: - result = DID_ABORT << 16; - DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: aborted cmd " - "returned\n", HD(cmd)->HBA_number)); - break; - case HA_CP_RESET_NA: - case HA_CP_RESET: - HD(cmd)->resetlevel[cmd->device->channel] = 0; - result = DID_RESET << 16; - DBG(DBG_STATUS, printk(KERN_WARNING "scsi%d: reseted cmd " - "pid %ldreturned\n", - HD(cmd)->HBA_number, cmd->pid)); - case HA_SCSI_HUNG: /* SCSI Hung */ - printk(KERN_ERR "scsi%d: SCSI hung\n", HD(cmd)->HBA_number); - result = DID_ERROR << 16; - break; - case HA_RSENSE_FAIL: /* Auto Request-Sense Failed */ - DBG(DBG_STATUS, printk(KERN_ERR "scsi%d: Auto Request Sense " - "Failed\n", HD(cmd)->HBA_number)); - result = DID_ERROR << 16; - break; - case HA_UNX_BUSPHASE: /* Unexpected Bus Phase */ - case HA_UNX_BUS_FREE: /* Unexpected Bus Free */ - case HA_BUS_PARITY: /* Bus Parity Error */ - case HA_UNX_MSGRJCT: /* Unexpected Message Reject */ - case HA_RESET_STUCK: /* SCSI Bus Reset Stuck */ - case HA_PARITY_ERR: /* Controller Ram Parity */ - default: - result = DID_ERROR << 16; - break; - } - cmd->result = result | (scsi_stat << 1); - -#if DBG_INTR2 - if (scsi_stat || result || hba_stat || eata_stat != 0x50 - || cmd->scsi_done == NULL || cmd->device->id == 7) - printk("HBA: %d, channel %d, id: %d, lun %d, pid %ld:\n" - "eata_stat %#x, hba_stat %#.2x, scsi_stat %#.2x, " - "sense_key: %#x, result: %#.8x\n", x, - cmd->device->channel, cmd->device->id, cmd->device->lun, - cmd->pid, eata_stat, hba_stat, scsi_stat, - cmd->sense_buffer[2] & 0xf, cmd->result); - DBG(DBG_INTR&&DBG_DELAY,DELAY(1)); -#endif - - ccb->status = FREE; /* now we can release the slot */ - cmd->scsi_done(cmd); - } - } - - return; -} - -inline int eata_send_command(u32 addr, u32 base, u8 command) -{ - long loop = R_LIMIT; - - while (inb(base + HA_RAUXSTAT) & HA_ABUSY) - if (--loop == 0) - return(FALSE); - - if(addr != (u32) NULL) - addr = virt_to_bus((void *)addr); - - /* - * This is overkill.....but the MIPSen seem to need this - * and it will be optimized away for i86 and ALPHA machines. - */ - flush_cache_all(); - - /* And now the address in nice little byte chunks */ -#ifdef __LITTLE_ENDIAN - outb(addr, base + HA_WDMAADDR); - outb(addr >> 8, base + HA_WDMAADDR + 1); - outb(addr >> 16, base + HA_WDMAADDR + 2); - outb(addr >> 24, base + HA_WDMAADDR + 3); -#else - outb(addr >> 24, base + HA_WDMAADDR); - outb(addr >> 16, base + HA_WDMAADDR + 1); - outb(addr >> 8, base + HA_WDMAADDR + 2); - outb(addr, base + HA_WDMAADDR + 3); -#endif - outb(command, base + HA_WCOMMAND); - return(TRUE); -} - -inline int eata_send_immediate(u32 base, u32 addr, u8 ifc, u8 code, u8 code2) -{ - if(addr != (u32) NULL) - addr = virt_to_bus((void *)addr); - - /* - * This is overkill.....but the MIPSen seem to need this - * and it will be optimized away for i86 and ALPHA machines. - */ - flush_cache_all(); - - outb(0x0, base + HA_WDMAADDR - 1); - if(addr){ -#ifdef __LITTLE_ENDIAN - outb(addr, base + HA_WDMAADDR); - outb(addr >> 8, base + HA_WDMAADDR + 1); - outb(addr >> 16, base + HA_WDMAADDR + 2); - outb(addr >> 24, base + HA_WDMAADDR + 3); -#else - outb(addr >> 24, base + HA_WDMAADDR); - outb(addr >> 16, base + HA_WDMAADDR + 1); - outb(addr >> 8, base + HA_WDMAADDR + 2); - outb(addr, base + HA_WDMAADDR + 3); -#endif - } else { - outb(0x0, base + HA_WDMAADDR); - outb(0x0, base + HA_WDMAADDR + 1); - outb(code2, base + HA_WCODE2); - outb(code, base + HA_WCODE); - } - - outb(ifc, base + HA_WIFC); - outb(EATA_CMD_IMMEDIATE, base + HA_WCOMMAND); - return(TRUE); -} - -int eata_queue(Scsi_Cmnd * cmd, void (* done) (Scsi_Cmnd *)) -{ - unsigned int i, x, y; - ulong flags; - hostdata *hd; - struct Scsi_Host *sh; - struct eata_ccb *ccb; - struct scatterlist *sl; - - - save_flags(flags); - cli(); - -#if 0 - for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { - if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { - printk("eata_dma: scsi%d interrupt pending in eata_queue.\n" - " Calling interrupt handler.\n", sh->host_no); - eata_int_handler(sh->irq, 0, 0); - } - } -#endif - - queue_counter++; - - hd = HD(cmd); - sh = cmd->device->host; - - if (cmd->cmnd[0] == REQUEST_SENSE && cmd->sense_buffer[0] != 0) { - DBG(DBG_REQSENSE, printk(KERN_DEBUG "Tried to REQUEST SENSE\n")); - cmd->result = DID_OK << 16; - done(cmd); - restore_flags(flags); - - return(0); - } - - /* check for free slot */ - for (y = hd->last_ccb + 1, x = 0; x < sh->can_queue; x++, y++) { - if (y >= sh->can_queue) - y = 0; - if (hd->ccb[y].status == FREE) - break; - } - - hd->last_ccb = y; - - if (x >= sh->can_queue) { - cmd->result = DID_BUS_BUSY << 16; - DBG(DBG_QUEUE && DBG_ABNORM, - printk(KERN_CRIT "eata_queue pid %ld, HBA QUEUE FULL..., " - "returning DID_BUS_BUSY\n", cmd->pid)); - done(cmd); - restore_flags(flags); - return(0); - } - ccb = &hd->ccb[y]; - - memset(ccb, 0, sizeof(struct eata_ccb) - sizeof(struct eata_sg_list *)); - - ccb->status = USED; /* claim free slot */ - - restore_flags(flags); - - DBG(DBG_QUEUE, printk("eata_queue pid %ld, target: %x, lun: %x, y %d\n", - cmd->pid, cmd->device->id, cmd->device->lun, y)); - DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); - - if(hd->do_latency == TRUE) - eata_latency_out(ccb, cmd); - - cmd->scsi_done = (void *)done; - - switch (cmd->cmnd[0]) { - case CHANGE_DEFINITION: case COMPARE: case COPY: - case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: - case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER: - case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: - case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: - case WRITE_6: case WRITE_10: case WRITE_VERIFY: - case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: - case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: - case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: - case MEDIUM_SCAN: case SEND_VOLUME_TAG: - case 0xea: /* alternate number for WRITE LONG */ - ccb->DataOut = TRUE; /* Output mode */ - break; - case TEST_UNIT_READY: - default: - ccb->DataIn = TRUE; /* Input mode */ - } - - /* FIXME: This will will have to be changed once the midlevel driver - * allows different HBA IDs on every channel. - */ - if (cmd->device->id == sh->this_id) - ccb->Interpret = TRUE; /* Interpret command */ - - if (cmd->use_sg) { - ccb->scatter = TRUE; /* SG mode */ - if (ccb->sg_list == NULL) { - ccb->sg_list = kmalloc(sh->sg_tablesize * sizeof(struct eata_sg_list), - GFP_ATOMIC | GFP_DMA); - } - if (ccb->sg_list == NULL) - { - /* - * Claim the bus was busy. Actually we are the problem but this - * will do a deferred retry for us ;) - */ - printk(KERN_ERR "eata_dma: Run out of DMA memory for SG lists !\n"); - cmd->result = DID_BUS_BUSY << 16; - ccb->status = FREE; - done(cmd); - return(0); - } - ccb->cp_dataDMA = htonl(virt_to_bus(ccb->sg_list)); - - ccb->cp_datalen = htonl(cmd->use_sg * sizeof(struct eata_sg_list)); - sl=(struct scatterlist *)cmd->request_buffer; - for(i = 0; i < cmd->use_sg; i++, sl++){ - ccb->sg_list[i].data = htonl(virt_to_bus(sl->address)); - ccb->sg_list[i].len = htonl((u32) sl->length); - } - } else { - ccb->scatter = FALSE; - ccb->cp_datalen = htonl(cmd->request_bufflen); - ccb->cp_dataDMA = htonl(virt_to_bus(cmd->request_buffer)); - } - - ccb->Auto_Req_Sen = TRUE; - ccb->cp_reqDMA = htonl(virt_to_bus(cmd->sense_buffer)); - ccb->reqlen = sizeof(cmd->sense_buffer); - - ccb->cp_id = cmd->device->id; - ccb->cp_channel = cmd->device->channel; - ccb->cp_lun = cmd->device->lun; - ccb->cp_dispri = TRUE; - ccb->cp_identify = TRUE; - memcpy(ccb->cp_cdb, cmd->cmnd, cmd->cmd_len); - - ccb->cp_statDMA = htonl(virt_to_bus(&(hd->sp))); - - ccb->cp_viraddr = ccb; /* This will be passed thru, so we don't need to - * convert it */ - ccb->cmd = cmd; - cmd->host_scribble = (char *)&hd->ccb[y]; - - if(eata_send_command((u32) ccb, (u32) sh->base, EATA_CMD_DMA_SEND_CP) == FALSE) { - cmd->result = DID_BUS_BUSY << 16; - DBG(DBG_QUEUE && DBG_ABNORM, - printk("eata_queue target %d, pid %ld, HBA busy, " - "returning DID_BUS_BUSY\n",cmd->device->id, cmd->pid)); - ccb->status = FREE; - done(cmd); - return(0); - } - DBG(DBG_QUEUE, printk("Queued base %#.4x pid: %ld target: %x lun: %x " - "slot %d irq %d\n", (s32)sh->base, cmd->pid, - cmd->device->id, cmd->device->lun, y, sh->irq)); - DBG(DBG_QUEUE && DBG_DELAY, DELAY(1)); - - return(0); -} - - -int eata_abort(Scsi_Cmnd * cmd) -{ - ulong loop = HZ / 2; - ulong flags; - int x; - struct Scsi_Host *sh; - - save_flags(flags); - cli(); - - DBG(DBG_ABNORM, printk("eata_abort called pid: %ld target: %x lun: %x" - " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, - cmd->abort_reason)); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - - /* Some interrupt controllers seem to loose interrupts */ - for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { - if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { - printk("eata_dma: scsi%d interrupt pending in eata_abort.\n" - " Calling interrupt handler.\n", sh->host_no); - eata_int_handler(sh->irq, 0, 0); - } - } - - while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY) { - if (--loop == 0) { - printk("eata_dma: abort, timeout error.\n"); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - restore_flags(flags); - return (SCSI_ABORT_ERROR); - } - } - if (CD(cmd)->status == RESET) { - printk("eata_dma: abort, command reset error.\n"); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - restore_flags(flags); - return (SCSI_ABORT_ERROR); - } - if (CD(cmd)->status == LOCKED) { - DBG(DBG_ABNORM, printk("eata_dma: abort, queue slot locked.\n")); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - restore_flags(flags); - return (SCSI_ABORT_NOT_RUNNING); - } - if (CD(cmd)->status == USED) { - DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_BUSY\n")); - restore_flags(flags); - return (SCSI_ABORT_BUSY); /* SNOOZE */ - } - if (CD(cmd)->status == FREE) { - DBG(DBG_ABNORM, printk("Returning: SCSI_ABORT_NOT_RUNNING\n")); - restore_flags(flags); - return (SCSI_ABORT_NOT_RUNNING); - } - restore_flags(flags); - panic("eata_dma: abort: invalid slot status\n"); -} - -int eata_reset(Scsi_Cmnd * cmd, unsigned int resetflags) -{ - uint x; - /* 10 million PCI reads take at least one third of a second */ - ulong loop = 10 * 1000 * 1000; - ulong flags; - unchar success = FALSE; - Scsi_Cmnd *sp; - struct Scsi_Host *sh; - - save_flags(flags); - cli(); - - DBG(DBG_ABNORM, printk("eata_reset called pid:%ld target: %x lun: %x" - " reason %x\n", cmd->pid, cmd->device->id, cmd->device->lun, - cmd->abort_reason)); - - for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->next) { - if(inb((uint)sh->base + HA_RAUXSTAT) & HA_AIRQ) { - printk("eata_dma: scsi%d interrupt pending in eata_reset.\n" - " Calling interrupt handler.\n", sh->host_no); - eata_int_handler(sh->irq, 0, 0); - } - } - - if (HD(cmd)->state == RESET) { - printk("eata_reset: exit, already in reset.\n"); - restore_flags(flags); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - return (SCSI_RESET_ERROR); - } - - while (inb((u32)(cmd->device->host->base) + HA_RAUXSTAT) & HA_ABUSY) - if (--loop == 0) { - printk("eata_reset: exit, timeout error.\n"); - restore_flags(flags); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - return (SCSI_RESET_ERROR); - } - - for (x = 0; x < cmd->device->host->can_queue; x++) { - if (HD(cmd)->ccb[x].status == FREE) - continue; - - if (HD(cmd)->ccb[x].status == LOCKED) { - HD(cmd)->ccb[x].status = FREE; - printk("eata_reset: locked slot %d forced free.\n", x); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - continue; - } - - - sp = HD(cmd)->ccb[x].cmd; - HD(cmd)->ccb[x].status = RESET; - - if (sp == NULL) - panic("eata_reset: slot %d, sp==NULL.\n", x); - - printk("eata_reset: slot %d in reset, pid %ld.\n", x, sp->pid); - - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - - if (sp == cmd) - success = TRUE; - } - - /* hard reset the HBA */ - inb((u32) (cmd->device->host->base) + HA_RSTATUS); /* This might cause trouble */ - eata_send_command(0, (u32) cmd->device->host->base, EATA_CMD_RESET); - - HD(cmd)->state = RESET; - - DBG(DBG_ABNORM, printk("eata_reset: board reset done, enabling " - "interrupts.\n")); - - DELAY(2); /* In theorie we should get interrupts and set free all - * used queueslots */ - - DBG(DBG_ABNORM, printk("eata_reset: interrupts disabled again.\n")); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - - for (x = 0; x < cmd->device->host->can_queue; x++) { - - /* Skip slots already set free by interrupt and those that - * are still LOCKED from the last reset */ - if (HD(cmd)->ccb[x].status != RESET) - continue; - - sp = HD(cmd)->ccb[x].cmd; - sp->result = DID_RESET << 16; - - /* This mailbox is still waiting for its interrupt */ - HD(cmd)->ccb[x].status = LOCKED; - - printk("eata_reset: slot %d locked, DID_RESET, pid %ld done.\n", - x, sp->pid); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - - sp->scsi_done(sp); - } - - HD(cmd)->state = FALSE; - restore_flags(flags); - - if (success) { - DBG(DBG_ABNORM, printk("eata_reset: exit, pending.\n")); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - return (SCSI_RESET_PENDING); - } else { - DBG(DBG_ABNORM, printk("eata_reset: exit, wakeup.\n")); - DBG(DBG_ABNORM && DBG_DELAY, DELAY(1)); - return (SCSI_RESET_PUNT); - } -} - -/* Here we try to determine the optimum queue depth for - * each attached device. - * - * At the moment the algorithm is rather simple - */ -static void eata_select_queue_depths(struct Scsi_Host *host, - Scsi_Device *devicelist) -{ - Scsi_Device *device; - int devcount = 0; - int factor = 0; - -#if CRIPPLE_QUEUE - for(device = devicelist; device != NULL; device = device->next) { - if(device->host == host) - device->queue_depth = 2; - } -#else - /* First we do a sample run go find out what we have */ - for(device = devicelist; device != NULL; device = device->next) { - if (device->host == host) { - devcount++; - switch(device->type) { - case TYPE_DISK: - case TYPE_MOD: - factor += TYPE_DISK_QUEUE; - break; - case TYPE_TAPE: - factor += TYPE_TAPE_QUEUE; - break; - case TYPE_WORM: - case TYPE_ROM: - factor += TYPE_ROM_QUEUE; - break; - case TYPE_PROCESSOR: - case TYPE_SCANNER: - default: - factor += TYPE_OTHER_QUEUE; - break; - } - } - } - - DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: needed queueslots %d\n", - host->host_no, factor)); - - if(factor == 0) /* We don't want to get a DIV BY ZERO error */ - factor = 1; - - factor = (SD(host)->queuesize * 10) / factor; - - DBG(DBG_REGISTER, printk(KERN_DEBUG "scsi%d: using factor %dE-1\n", - host->host_no, factor)); - - /* Now that have the factor we can set the individual queuesizes */ - for(device = devicelist; device != NULL; device = device->next) { - if(device->host == host) { - if(SD(device->host)->bustype != IS_ISA){ - switch(device->type) { - case TYPE_DISK: - case TYPE_MOD: - device->queue_depth = (TYPE_DISK_QUEUE * factor) / 10; - break; - case TYPE_TAPE: - device->queue_depth = (TYPE_TAPE_QUEUE * factor) / 10; - break; - case TYPE_WORM: - case TYPE_ROM: - device->queue_depth = (TYPE_ROM_QUEUE * factor) / 10; - break; - case TYPE_PROCESSOR: - case TYPE_SCANNER: - default: - device->queue_depth = (TYPE_OTHER_QUEUE * factor) / 10; - break; - } - } else /* ISA forces us to limit the queue depth because of the - * bounce buffer memory overhead. I know this is cruel */ - device->queue_depth = 2; - - /* - * It showed that we need to set an upper limit of commands - * we can allow to queue for a single device on the bus. - * If we get above that limit, the broken midlevel SCSI code - * will produce bogus timeouts and aborts en masse. :-( - */ - if(device->queue_depth > UPPER_DEVICE_QUEUE_LIMIT) - device->queue_depth = UPPER_DEVICE_QUEUE_LIMIT; - if(device->queue_depth == 0) - device->queue_depth = 1; - - printk(KERN_INFO "scsi%d: queue depth for target %d on channel %d " - "set to %d\n", host->host_no, device->id, device->channel, - device->queue_depth); - } - } -#endif -} - -#if CHECK_BLINK -int check_blink_state(long base) -{ - ushort loops = 10; - u32 blinkindicator; - u32 state = 0x12345678; - u32 oldstate = 0; - - blinkindicator = htonl(0x54504442); - while ((loops--) && (state != oldstate)) { - oldstate = state; - state = inl((uint) base + 1); - } - - DBG(DBG_BLINK, printk("Did Blink check. Status: %d\n", - (state == oldstate) && (state == blinkindicator))); - - if ((state == oldstate) && (state == blinkindicator)) - return(TRUE); - else - return (FALSE); -} -#endif - -char * get_board_data(u32 base, u32 irq, u32 id) -{ - struct eata_ccb *cp; - struct eata_sp *sp; - static char *buff; - ulong i; - - cp = (struct eata_ccb *) kmalloc(sizeof(struct eata_ccb), - GFP_ATOMIC | GFP_DMA); - - if(cp==NULL) - return NULL; - - sp = (struct eata_sp *) kmalloc(sizeof(struct eata_sp), - GFP_ATOMIC | GFP_DMA); - if(sp==NULL) - { - kfree(cp); - return NULL; - } - - buff = dma_scratch; - - memset(cp, 0, sizeof(struct eata_ccb)); - memset(sp, 0, sizeof(struct eata_sp)); - memset(buff, 0, 256); - - cp->DataIn = TRUE; - cp->Interpret = TRUE; /* Interpret command */ - cp->cp_dispri = TRUE; - cp->cp_identify = TRUE; - - cp->cp_datalen = htonl(56); - cp->cp_dataDMA = htonl(virt_to_bus(buff)); - cp->cp_statDMA = htonl(virt_to_bus(sp)); - cp->cp_viraddr = cp; - - cp->cp_id = id; - cp->cp_lun = 0; - - cp->cp_cdb[0] = INQUIRY; - cp->cp_cdb[1] = 0; - cp->cp_cdb[2] = 0; - cp->cp_cdb[3] = 0; - cp->cp_cdb[4] = 56; - cp->cp_cdb[5] = 0; - - fake_int_base = (struct eata_register *) base; - fake_int_result = FALSE; - fake_int_happened = FALSE; - - eata_send_command((u32) cp, (u32) base, EATA_CMD_DMA_SEND_CP); - - i = jiffies + (3 * HZ); - while (fake_int_happened == FALSE && time_before_eq(jiffies, i)) - barrier(); - - DBG(DBG_INTR3, printk(KERN_DEBUG "fake_int_result: %#x hbastat %#x " - "scsistat %#x, buff %p sp %p\n", - fake_int_result, (u32) (sp->hba_stat /*& 0x7f*/), - (u32) sp->scsi_stat, buff, sp)); - - kfree((void *)cp); - kfree((void *)sp); - - if ((fake_int_result & HA_SERROR) || time_after(jiffies, i)){ - printk(KERN_WARNING "eata_dma: trying to reset HBA at %x to clear " - "possible blink state\n", base); - /* hard reset the HBA */ - inb((u32) (base) + HA_RSTATUS); - eata_send_command(0, base, EATA_CMD_RESET); - DELAY(1); - return (NULL); - } else - return (buff); -} - - -int get_conf_PIO(u32 base, struct get_conf *buf) -{ - ulong loop = R_LIMIT; - u16 *p; - - if(check_region(base, 9)) - return (FALSE); - - memset(buf, 0, sizeof(struct get_conf)); - - while (inb(base + HA_RSTATUS) & HA_SBUSY) - if (--loop == 0) - return (FALSE); - - fake_int_base = (struct eata_register *) base; - fake_int_result = FALSE; - fake_int_happened = FALSE; - - DBG(DBG_PIO && DBG_PROBE, - printk("Issuing PIO READ CONFIG to HBA at %#x\n", base)); - eata_send_command(0, base, EATA_CMD_PIO_READ_CONFIG); - - loop = R_LIMIT; - for (p = (u16 *) buf; - (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) { - while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) - if (--loop == 0) - return (FALSE); - - loop = R_LIMIT; - *p = inw(base + HA_RDATA); - } - - if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { /* Error ? */ - if (htonl(EATA_SIGNATURE) == buf->signature) { - DBG(DBG_PIO&&DBG_PROBE, printk("EATA Controller found at %x " - "EATA Level: %x\n", (uint) base, - (uint) (buf->version))); - - while (inb(base + HA_RSTATUS) & HA_SDRQ) - inw(base + HA_RDATA); - return (TRUE); - } - } else { - DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer " - "for HBA at %lx\n", (long)base)); - } - return (FALSE); -} - - -void print_config(struct get_conf *gc) -{ - printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d DMAS:%d\n", - (u32) ntohl(gc->len), gc->version, - gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support, - gc->DMA_support); - printk("DMAV:%d HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", - gc->DMA_valid, gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], - gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND); - printk("IRQ:%d IRQT:%d DMAC:%d FORCADR:%d SG_64K:%d SG_UAE:%d MID:%d " - "MCH:%d MLUN:%d\n", - gc->IRQ, gc->IRQ_TR, (8 - gc->DMA_channel) & 7, gc->FORCADR, - gc->SG_64K, gc->SG_UAE, gc->MAX_ID, gc->MAX_CHAN, gc->MAX_LUN); - printk("RIDQ:%d PCI:%d EISA:%d\n", - gc->ID_qest, gc->is_PCI, gc->is_EISA); - DBG(DPT_DEBUG, DELAY(14)); -} - -short register_HBA(u32 base, struct get_conf *gc, Scsi_Host_Template * tpnt, - u8 bustype) -{ - ulong size = 0; - unchar dma_channel = 0; - char *buff = 0; - unchar bugs = 0; - struct Scsi_Host *sh; - hostdata *hd; - int x; - - - DBG(DBG_REGISTER, print_config(gc)); - - if (gc->DMA_support == FALSE) { - printk("The EATA HBA at %#.4x does not support DMA.\n" - "Please use the EATA-PIO driver.\n", base); - return (FALSE); - } - if(gc->HAA_valid == FALSE || ntohl(gc->len) < 0x22) - gc->MAX_CHAN = 0; - - if (reg_IRQ[gc->IRQ] == FALSE) { /* Interrupt already registered ? */ - if (!request_irq(gc->IRQ, (void *) eata_fake_int_handler, SA_INTERRUPT, - "eata_dma", NULL)){ - reg_IRQ[gc->IRQ]++; - if (!gc->IRQ_TR) - reg_IRQL[gc->IRQ] = TRUE; /* IRQ is edge triggered */ - } else { - printk("Couldn't allocate IRQ %d, Sorry.", gc->IRQ); - return (FALSE); - } - } else { /* More than one HBA on this IRQ */ - if (reg_IRQL[gc->IRQ] == TRUE) { - printk("Can't support more than one HBA on this IRQ,\n" - " if the IRQ is edge triggered. Sorry.\n"); - return (FALSE); - } else - reg_IRQ[gc->IRQ]++; - } - - - /* If DMA is supported but DMA_valid isn't set to indicate that - * the channel number is given we must have pre 2.0 firmware (1.7?) - * which leaves us to guess since the "newer ones" also don't set the - * DMA_valid bit. - */ - if (gc->DMA_support && !gc->DMA_valid && gc->DMA_channel) { - printk(KERN_WARNING "eata_dma: If you are using a pre 2.0 firmware " - "please update it !\n" - " You can get new firmware releases from ftp.dpt.com\n"); - gc->DMA_channel = (base == 0x1f0 ? 3 /* DMA=5 */ : 2 /* DMA=6 */); - gc->DMA_valid = TRUE; - } - - /* if gc->DMA_valid it must be an ISA HBA and we have to register it */ - dma_channel = BUSMASTER; - if (gc->DMA_valid) { - if (request_dma(dma_channel = (8 - gc->DMA_channel) & 7, "eata_dma")) { - printk(KERN_WARNING "Unable to allocate DMA channel %d for ISA HBA" - " at %#.4x.\n", dma_channel, base); - reg_IRQ[gc->IRQ]--; - if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ, NULL); - if (gc->IRQ_TR == FALSE) - reg_IRQL[gc->IRQ] = FALSE; - return (FALSE); - } - } - - if (dma_channel != BUSMASTER) { - disable_dma(dma_channel); - clear_dma_ff(dma_channel); - set_dma_mode(dma_channel, DMA_MODE_CASCADE); - enable_dma(dma_channel); - } - - if (bustype != IS_EISA && bustype != IS_ISA) - buff = get_board_data(base, gc->IRQ, gc->scsi_id[3]); - - if (buff == NULL) { - if (bustype == IS_EISA || bustype == IS_ISA) { - bugs = bugs || BROKEN_INQUIRY; - } else { - if (gc->DMA_support == FALSE) - printk(KERN_WARNING "HBA at %#.4x doesn't support DMA. " - "Sorry\n", base); - else - printk(KERN_WARNING "HBA at %#.4x does not react on INQUIRY. " - "Sorry.\n", base); - if (gc->DMA_valid) - free_dma(dma_channel); - reg_IRQ[gc->IRQ]--; - if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ, NULL); - if (gc->IRQ_TR == FALSE) - reg_IRQL[gc->IRQ] = FALSE; - return (FALSE); - } - } - - if (gc->DMA_support == FALSE && buff != NULL) - printk(KERN_WARNING "HBA %.12sat %#.4x doesn't set the DMA_support " - "flag correctly.\n", &buff[16], base); - - request_region(base, 9, "eata_dma"); /* We already checked the - * availability, so this - * should not fail. - */ - - if(ntohs(gc->queuesiz) == 0) { - gc->queuesiz = ntohs(64); - printk(KERN_WARNING "Warning: Queue size has to be corrected. Assuming" - " 64 queueslots\n" - " This might be a PM2012B with a defective Firmware\n" - " Contact DPT support@dpt.com for an upgrade\n"); - } - - size = sizeof(hostdata) + ((sizeof(struct eata_ccb) + sizeof(long)) - * ntohs(gc->queuesiz)); - - DBG(DBG_REGISTER, printk("scsi_register size: %ld\n", size)); - - sh = scsi_register(tpnt, size); - - if(sh != NULL) { - - hd = SD(sh); - - memset(hd->reads, 0, sizeof(u32) * 26); - - sh->select_queue_depths = eata_select_queue_depths; - - hd->bustype = bustype; - - /* - * If we are using a ISA board, we can't use extended SG, - * because we would need excessive amounts of memory for - * bounce buffers. - */ - if (gc->SG_64K==TRUE && ntohs(gc->SGsiz)==64 && hd->bustype!=IS_ISA){ - sh->sg_tablesize = SG_SIZE_BIG; - } else { - sh->sg_tablesize = ntohs(gc->SGsiz); - if (sh->sg_tablesize > SG_SIZE || sh->sg_tablesize == 0) { - if (sh->sg_tablesize == 0) - printk(KERN_WARNING "Warning: SG size had to be fixed.\n" - "This might be a PM2012 with a defective Firmware" - "\nContact DPT support@dpt.com for an upgrade\n"); - sh->sg_tablesize = SG_SIZE; - } - } - hd->sgsize = sh->sg_tablesize; - } - - if(sh != NULL) { - sh->can_queue = hd->queuesize = ntohs(gc->queuesiz); - sh->cmd_per_lun = 0; - } - - if(sh == NULL) { - DBG(DBG_REGISTER, printk(KERN_NOTICE "eata_dma: couldn't register HBA" - " at%x \n", base)); - scsi_unregister(sh); - if (gc->DMA_valid) - free_dma(dma_channel); - - reg_IRQ[gc->IRQ]--; - if (reg_IRQ[gc->IRQ] == 0) - free_irq(gc->IRQ, NULL); - if (gc->IRQ_TR == FALSE) - reg_IRQL[gc->IRQ] = FALSE; - return (FALSE); - } - - - hd->broken_INQUIRY = (bugs & BROKEN_INQUIRY); - - if(hd->broken_INQUIRY == TRUE) { - strcpy(hd->vendor, "DPT"); - strcpy(hd->name, "??????????"); - strcpy(hd->revision, "???.?"); - hd->firmware_revision = 0; - } else { - strncpy(hd->vendor, &buff[8], 8); - hd->vendor[8] = 0; - strncpy(hd->name, &buff[16], 17); - hd->name[17] = 0; - hd->revision[0] = buff[32]; - hd->revision[1] = buff[33]; - hd->revision[2] = buff[34]; - hd->revision[3] = '.'; - hd->revision[4] = buff[35]; - hd->revision[5] = 0; - hd->firmware_revision = (buff[32] << 24) + (buff[33] << 16) - + (buff[34] << 8) + buff[35]; - } - - if (hd->firmware_revision >= (('0'<<24) + ('7'<<16) + ('G'<< 8) + '0')) - hd->immediate_support = 1; - else - hd->immediate_support = 0; - - switch (ntohl(gc->len)) { - case 0x1c: - hd->EATA_revision = 'a'; - break; - case 0x1e: - hd->EATA_revision = 'b'; - break; - case 0x22: - hd->EATA_revision = 'c'; - break; - case 0x24: - hd->EATA_revision = 'z'; - default: - hd->EATA_revision = '?'; - } - - - if(ntohl(gc->len) >= 0x22) { - sh->max_id = gc->MAX_ID + 1; - sh->max_lun = gc->MAX_LUN + 1; - } else { - sh->max_id = 8; - sh->max_lun = 8; - } - - hd->HBA_number = sh->host_no; - hd->channel = gc->MAX_CHAN; - sh->max_channel = gc->MAX_CHAN; - sh->unique_id = base; - sh->base = base; - sh->io_port = base; - sh->n_io_port = 9; - sh->irq = gc->IRQ; - sh->dma_channel = dma_channel; - - /* FIXME: - * SCSI midlevel code should support different HBA ids on every channel - */ - sh->this_id = gc->scsi_id[3]; - - if (gc->SECOND) - hd->primary = FALSE; - else - hd->primary = TRUE; - - if (hd->bustype != IS_ISA) { - sh->unchecked_isa_dma = FALSE; - } else { - sh->unchecked_isa_dma = TRUE; /* We're doing ISA DMA */ - } - - for(x = 0; x <= 11; x++){ /* Initialize min. latency */ - hd->writes_lat[x][1] = 0xffffffff; - hd->reads_lat[x][1] = 0xffffffff; - } - hd->all_lat[1] = 0xffffffff; - - hd->next = NULL; /* build a linked list of all HBAs */ - hd->prev = last_HBA; - if(hd->prev != NULL) - SD(hd->prev)->next = sh; - last_HBA = sh; - if (first_HBA == NULL) - first_HBA = sh; - registered_HBAs++; - - return (TRUE); -} - - - -void find_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt) -{ - u32 base; - int i; - -#if CHECKPAL - u8 pal1, pal2, pal3; -#endif - - for (i = 0; i < MAXEISA; i++) { - if (EISAbases[i] == TRUE) { /* Still a possibility ? */ - - base = 0x1c88 + (i * 0x1000); -#if CHECKPAL - pal1 = inb((u16)base - 8); - pal2 = inb((u16)base - 7); - pal3 = inb((u16)base - 6); - - if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || - ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && (pal3 == NEC_ID3))|| - ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && (pal3 == ATT_ID3))){ - DBG(DBG_PROBE, printk("EISA EATA id tags found: %x %x %x \n", - (int)pal1, (int)pal2, (int)pal3)); -#endif - if (get_conf_PIO(base, buf) == TRUE) { - if (buf->IRQ) { - DBG(DBG_EISA, printk("Registering EISA HBA\n")); - register_HBA(base, buf, tpnt, IS_EISA); - } else - printk("eata_dma: No valid IRQ. HBA removed from list\n"); - } -#if CHECK_BLINK - else { - if (check_blink_state(base)) - printk("HBA is in BLINK state. Consult your HBAs " - "Manual to correct this.\n"); - } -#endif - /* Nothing found here so we take it from the list */ - EISAbases[i] = 0; -#if CHECKPAL - } -#endif - } - } - return; -} - -void find_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt) -{ - int i; - - for (i = 0; i < MAXISA; i++) { - if (ISAbases[i]) { - if (get_conf_PIO(ISAbases[i],buf) == TRUE){ - DBG(DBG_ISA, printk("Registering ISA HBA\n")); - register_HBA(ISAbases[i], buf, tpnt, IS_ISA); - } -#if CHECK_BLINK - else { - if (check_blink_state(ISAbases[i])) - printk("HBA is in BLINK state. Consult your HBAs " - "Manual to correct this.\n"); - } -#endif - ISAbases[i] = 0; - } - } - return; -} - -void find_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt) -{ -#ifndef CONFIG_PCI - printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); -#else - struct pci_dev *dev = NULL; - u32 base, x; - u8 pal1, pal2, pal3; - - while ((dev = pci_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { - DBG(DBG_PROBE && DBG_PCI, - printk("eata_dma: find_PCI, HBA at %s\n", dev->name)); - if (pci_enable_device(dev)) - continue; - pci_set_master(dev); - base = pci_resource_flags(dev, 0); - if (base & IORESOURCE_MEM) { - printk("eata_dma: invalid base address of device %s\n", dev->name); - continue; - } - base = pci_resource_start(dev, 0); - /* EISA tag there ? */ - pal1 = inb(base); - pal2 = inb(base + 1); - pal3 = inb(base + 2); - if (((pal1 == DPT_ID1) && (pal2 == DPT_ID2)) || - ((pal1 == NEC_ID1) && (pal2 == NEC_ID2) && - (pal3 == NEC_ID3)) || - ((pal1 == ATT_ID1) && (pal2 == ATT_ID2) && - (pal3 == ATT_ID3))) - base += 0x08; - else - base += 0x10; /* Now, THIS is the real address */ - if (base != 0x1f8) { - /* We didn't find it in the primary search */ - if (get_conf_PIO(base, buf) == TRUE) { - /* OK. We made it till here, so we can go now - * and register it. We only have to check and - * eventually remove it from the EISA and ISA list - */ - DBG(DBG_PCI, printk("Registering PCI HBA\n")); - register_HBA(base, buf, tpnt, IS_PCI); - - if (base < 0x1000) { - for (x = 0; x < MAXISA; ++x) { - if (ISAbases[x] == base) { - ISAbases[x] = 0; - break; - } - } - } else if ((base & 0x0fff) == 0x0c88) - EISAbases[(base >> 12) & 0x0f] = 0; - } -#if CHECK_BLINK - else if (check_blink_state(base) == TRUE) { - printk("eata_dma: HBA is in BLINK state.\n" - "Consult your HBAs manual to correct this.\n"); - } -#endif - } - } -#endif /* #ifndef CONFIG_PCI */ -} - -int eata_detect(Scsi_Host_Template * tpnt) -{ - struct Scsi_Host *HBA_ptr; - struct get_conf gc; - int i; - - DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG, - printk("Using lots of delays to let you read the debugging output\n")); - - tpnt->proc_name = "eata_dma"; - - status = kmalloc(512, GFP_ATOMIC | GFP_DMA); - dma_scratch = kmalloc(1024, GFP_ATOMIC | GFP_DMA); - - if(status == NULL || dma_scratch == NULL) { - printk("eata_dma: can't allocate enough memory to probe for hosts !\n"); - if(status) - kfree(status); - if(dma_scratch) - kfree(dma_scratch); - return(0); - } - - dma_scratch += 4; - - find_PCI(&gc, tpnt); - - find_EISA(&gc, tpnt); - - find_ISA(&gc, tpnt); - - for (i = 0; i <= MAXIRQ; i++) { /* Now that we know what we have, we */ - if (reg_IRQ[i] >= 1){ /* exchange the interrupt handler which */ - free_irq(i, NULL); /* we used for probing with the real one */ - request_irq(i, (void *)(do_eata_int_handler), SA_INTERRUPT|SA_SHIRQ, - "eata_dma", first_HBA); /* Check it */ - } - } - - HBA_ptr = first_HBA; - - if (registered_HBAs != 0) { - printk("EATA (Extended Attachment) driver version: %d.%d%s" - "\ndeveloped in co-operation with DPT\n" - "(c) 1993-96 Michael Neuffer, mike@i-Connect.Net\n", - VER_MAJOR, VER_MINOR, VER_SUB); - printk("Registered HBAs:"); - printk("\nHBA no. Boardtype Revis EATA Bus BaseIO IRQ" - " DMA Ch ID Pr QS S/G IS\n"); - for (i = 1; i <= registered_HBAs; i++) { - printk("scsi%-2d: %.12s v%s 2.0%c %s %#.4x %2d", - HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, - SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')? - "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ", - (u32) HBA_ptr->base, HBA_ptr->irq); - if(HBA_ptr->dma_channel != BUSMASTER) - printk(" %2x ", HBA_ptr->dma_channel); - else - printk(" %s", "BMST"); - printk(" %d %d %c %3d %3d %c\n", - SD(HBA_ptr)->channel+1, HBA_ptr->this_id, - (SD(HBA_ptr)->primary == TRUE)?'Y':'N', - HBA_ptr->can_queue, HBA_ptr->sg_tablesize, - (SD(HBA_ptr)->immediate_support == TRUE)?'Y':'N'); - HBA_ptr = SD(HBA_ptr)->next; - } - } else { - kfree((void *)status); - } - - kfree((void *)dma_scratch - 4); - - DBG(DPT_DEBUG, DELAY(12)); - - return(registered_HBAs); -} - -MODULE_LICENSE("GPL"); - -/* Eventually this will go into an include file, but this will be later */ -static Scsi_Host_Template driver_template = EATA_DMA; -#include "scsi_module.c" - -/* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * tab-width: 8 - * End: - */ diff -Nru a/drivers/scsi/eata_dma.h b/drivers/scsi/eata_dma.h --- a/drivers/scsi/eata_dma.h Tue Feb 18 01:03:48 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,114 +0,0 @@ -/******************************************************** -* Header file for eata_dma.c Linux EATA-DMA SCSI driver * -* (c) 1993-96 Michael Neuffer * -* mike@i-Connect.Net * -* neuffer@mail.uni-mainz.de * -********************************************************* -* last change: 96/10/14 * -********************************************************/ - -#ifndef _EATA_DMA_H -#define _EATA_DMA_H - -#include "eata_generic.h" - - -#define VER_MAJOR 2 -#define VER_MINOR 5 -#define VER_SUB "9b" - - -/************************************************************************ - * Here you can switch parts of the code on and of * - ************************************************************************/ - -#define CHECKPAL 0 /* EISA pal checking on/off */ -#define CHECK_BLINK 1 /* Switch Blink state check off, might * - * be nessessary for some MIPS machines*/ -#define CRIPPLE_QUEUE 0 /* Only enable this if the interrupt - * controller on your motherboard is - * broken and you are experiencing - * massive interrupt losses */ - -/************************************************************************ - * Debug options. * - * Enable DEBUG and whichever options you require. * - ************************************************************************/ -#define DEBUG_EATA 1 /* Enable debug code. */ -#define DPT_DEBUG 0 /* Bobs special */ -#define DBG_DELAY 0 /* Build in delays so debug messages can be - * be read before they vanish of the top of - * the screen! */ -#define DBG_PROBE 0 /* Debug probe routines. */ -#define DBG_PCI 0 /* Trace PCI routines */ -#define DBG_EISA 0 /* Trace EISA routines */ -#define DBG_ISA 0 /* Trace ISA routines */ -#define DBG_BLINK 0 /* Trace Blink check */ -#define DBG_PIO 0 /* Trace get_config_PIO */ -#define DBG_COM 0 /* Trace command call */ -#define DBG_QUEUE 0 /* Trace command queueing. */ -#define DBG_QUEUE2 0 /* Trace command queueing SG. */ -#define DBG_INTR 0 /* Trace interrupt service routine. */ -#define DBG_INTR2 0 /* Trace interrupt service routine. */ -#define DBG_INTR3 0 /* Trace get_board_data interrupts. */ -#define DBG_REQSENSE 0 /* Trace request sense commands */ -#define DBG_RESET 0 /* Trace reset calls */ -#define DBG_STATUS 0 /* Trace status generation */ -#define DBG_PROC 0 /* Debug proc-fs related statistics */ -#define DBG_PROC_WRITE 0 -#define DBG_REGISTER 0 /* */ -#define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort)*/ - -#if DEBUG_EATA -#define DBG(x, y) if ((x)) {y;} -#else -#define DBG(x, y) -#endif - -int eata_detect(Scsi_Host_Template *); -const char *eata_info(struct Scsi_Host *); -int eata_command(Scsi_Cmnd *); -int eata_queue(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *)); -int eata_abort(Scsi_Cmnd *); -int eata_reset(Scsi_Cmnd *, unsigned int); -int eata_proc_info(char *, char **, off_t, int, int, int); -#ifdef MODULE -int eata_release(struct Scsi_Host *); -#else -#define eata_release NULL -#endif - -#include - -#define EATA_DMA { \ - .proc_info = eata_proc_info, /* procinfo */ \ - .name = "EATA (Extended Attachment) HBA driver", \ - .detect = eata_detect, \ - .release = eata_release, \ - .queuecommand = eata_queue, \ - .abort = eata_abort, \ - .reset = eata_reset, \ - .unchecked_isa_dma = 1, /* True if ISA */ \ - .use_clustering = ENABLE_CLUSTERING } - - -#endif /* _EATA_DMA_H */ - -/* - * Overrides for Emacs so that we almost follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ diff -Nru a/drivers/scsi/eata_dma_proc.c b/drivers/scsi/eata_dma_proc.c --- a/drivers/scsi/eata_dma_proc.c Tue Feb 18 01:03:47 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,478 +0,0 @@ -void swap_statistics(u8 *p) -{ - u32 y; - u32 *lp, h_lp; - u16 *sp, h_sp; - u8 *bp; - - lp = (u32 *)p; - sp = ((short *)lp) + 1; /* Convert Header */ - h_sp = *sp = ntohs(*sp); - lp++; - - do { - sp = (u16 *)lp; /* Convert SubHeader */ - *sp = ntohs(*sp); - bp = (u8 *) lp; - y = *(bp + 3); - lp++; - for (h_lp = (u32)lp; (u32)lp < h_lp + ((u32)*(bp + 3)); lp++) - *lp = ntohl(*lp); - }while ((u32)lp < ((u32)p) + 4 + h_sp); - -} - -/* - * eata_set_info - * buffer : pointer to the data that has been written to the hostfile - * length : number of bytes written to the hostfile - * HBA_ptr: pointer to the Scsi_Host struct - */ -int eata_set_info(char *buffer, int length, struct Scsi_Host *HBA_ptr) -{ - int orig_length = length; - - if (length >= 8 && strncmp(buffer, "eata_dma", 8) == 0) { - buffer += 9; - length -= 9; - if(length >= 8 && strncmp(buffer, "latency", 7) == 0) { - SD(HBA_ptr)->do_latency = TRUE; - return(orig_length); - } - - if(length >=10 && strncmp(buffer, "nolatency", 9) == 0) { - SD(HBA_ptr)->do_latency = FALSE; - return(orig_length); - } - - printk("Unknown command:%s length: %d\n", buffer, length); - } else - printk("Wrong Signature:%10s\n", buffer); - - return(-EINVAL); -} - -/* - * eata_proc_info - * inout : decides on the direction of the dataflow and the meaning of the - * variables - * buffer: If inout==FALSE data is being written to it else read from it - * *start: If inout==FALSE start of the valid data in the buffer - * offset: If inout==FALSE offset from the beginning of the imaginary file - * from which we start writing into the buffer - * length: If inout==FALSE max number of bytes to be written into the buffer - * else number of bytes in the buffer - */ -int eata_proc_info(char *buffer, char **start, off_t offset, int length, - int hostno, int inout) -{ - - Scsi_Device *scd, *SDev; - struct Scsi_Host *HBA_ptr; - Scsi_Request * scmd; - char cmnd[MAX_COMMAND_SIZE]; - static u8 buff[512]; - static u8 buff2[512]; - hst_cmd_stat *rhcs, *whcs; - coco *cc; - scsitrans *st; - scsimod *sm; - hobu *hb; - scbu *sb; - boty *bt; - memco *mc; - firm *fm; - subinf *si; - pcinf *pi; - arrlim *al; - int i, x; - int size, len = 0; - off_t begin = 0; - off_t pos = 0; - scd = NULL; - - HBA_ptr = first_HBA; - for (i = 1; i <= registered_HBAs; i++) { - if (HBA_ptr->host_no == hostno) - break; - HBA_ptr = SD(HBA_ptr)->next; - } - - if(inout == TRUE) /* Has data been written to the file ? */ - return(eata_set_info(buffer, length, HBA_ptr)); - - if (offset == 0) - memset(buff, 0, sizeof(buff)); - - cc = (coco *) (buff + 0x148); - st = (scsitrans *)(buff + 0x164); - sm = (scsimod *) (buff + 0x16c); - hb = (hobu *) (buff + 0x172); - sb = (scbu *) (buff + 0x178); - bt = (boty *) (buff + 0x17e); - mc = (memco *) (buff + 0x186); - fm = (firm *) (buff + 0x18e); - si = (subinf *) (buff + 0x196); - pi = (pcinf *) (buff + 0x19c); - al = (arrlim *) (buff + 0x1a2); - - size = sprintf(buffer+len, "EATA (Extended Attachment) driver version: " - "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); - len += size; pos = begin + len; - size = sprintf(buffer + len, "queued commands: %10ld\n" - "processed interrupts:%10ld\n", queue_counter, int_counter); - len += size; pos = begin + len; - - size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", - HBA_ptr->host_no, SD(HBA_ptr)->name); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Firmware revision: v%s\n", - SD(HBA_ptr)->revision); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Hardware Configuration:\n"); - len += size; - pos = begin + len; - - if(SD(HBA_ptr)->broken_INQUIRY == TRUE) { - if (HBA_ptr->dma_channel == BUSMASTER) - size = sprintf(buffer + len, "DMA: BUSMASTER\n"); - else - size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel); - len += size; - pos = begin + len; - - size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base); - len += size; - pos = begin + len; - - size = sprintf(buffer + len, "Host Bus: EISA\n"); - len += size; - pos = begin + len; - - } else { - SDev = scsi_get_host_dev(HBA_ptr); - - if(SDev == NULL) - return -ENOMEM; - - scmd = scsi_allocate_request(SDev); - - if(scmd == NULL) - { - scsi_free_host_dev(SDev); - return -ENOMEM; - } - - - cmnd[0] = LOG_SENSE; - cmnd[1] = 0; - cmnd[2] = 0x33 + (3<<6); - cmnd[3] = 0; - cmnd[4] = 0; - cmnd[5] = 0; - cmnd[6] = 0; - cmnd[7] = 0x00; - cmnd[8] = 0x66; - cmnd[9] = 0; - - scmd->sr_cmd_len = 10; - scmd->sr_data_direction = SCSI_DATA_READ; - - /* - * Do the command and wait for it to finish. - */ - scsi_wait_req (scmd, cmnd, buff + 0x144, 0x66, - 1 * HZ, 1); - - size = sprintf(buffer + len, "IRQ: %2d, %s triggered\n", cc->interrupt, - (cc->intt == TRUE)?"level":"edge"); - len += size; - pos = begin + len; - if (HBA_ptr->dma_channel == 0xff) - size = sprintf(buffer + len, "DMA: BUSMASTER\n"); - else - size = sprintf(buffer + len, "DMA: %d\n", HBA_ptr->dma_channel); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "CPU: MC680%02d %dMHz\n", bt->cpu_type, - bt->cpu_speed); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) HBA_ptr->base); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Host Bus: %s\n", - (SD(HBA_ptr)->bustype == IS_PCI)?"PCI ": - (SD(HBA_ptr)->bustype == IS_EISA)?"EISA":"ISA "); - - len += size; - pos = begin + len; - size = sprintf(buffer + len, "SCSI Bus:%s%s Speed: %sMB/sec. %s\n", - (sb->wide == TRUE)?" WIDE":"", - (sb->dif == TRUE)?" DIFFERENTIAL":"", - (sb->speed == 0)?"5":(sb->speed == 1)?"10":"20", - (sb->ext == TRUE)?"With external cable detection":""); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "SCSI channel expansion Module: %s present\n", - (bt->sx1 == TRUE)?"SX1 (one channel)": - ((bt->sx2 == TRUE)?"SX2 (two channels)":"not")); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "SmartRAID hardware: %spresent.\n", - (cc->srs == TRUE)?"":"not "); - len += size; - pos = begin + len; - size = sprintf(buffer + len, " Type: %s\n", - ((cc->key == TRUE)?((bt->dmi == TRUE)?"integrated" - :((bt->dm4 == TRUE)?"DM401X" - :(bt->dm4k == TRUE)?"DM4000" - :"-")) - :"-")); - len += size; - pos = begin + len; - - size = sprintf(buffer + len, " Max array groups: %d\n", - (al->code == 0x0e)?al->max_groups:7); - len += size; - pos = begin + len; - size = sprintf(buffer + len, " Max drives per RAID 0 array: %d\n", - (al->code == 0x0e)?al->raid0_drv:7); - len += size; - pos = begin + len; - size = sprintf(buffer + len, " Max drives per RAID 3/5 array: %d\n", - (al->code == 0x0e)?al->raid35_drv:7); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Cache Module: %spresent.\n", - (cc->csh)?"":"not "); - len += size; - pos = begin + len; - size = sprintf(buffer + len, " Type: %s\n", - ((cc->csh == TRUE)?((bt->cmi == TRUE)?"integrated" - :((bt->cm4 == TRUE)?"CM401X" - :((bt->cm4k == TRUE)?"CM4000" - :"-"))) - :"-")); - len += size; - pos = begin + len; - for (x = 0; x <= 3; x++) { - size = sprintf(buffer + len, " Bank%d: %dMB with%s ECC\n",x, - mc->banksize[x] & 0x7f, - (mc->banksize[x] & 0x80)?"":"out"); - len += size; - pos = begin + len; - } - size = sprintf(buffer + len, "Timer Mod.: %spresent\n", - (cc->tmr == TRUE)?"":"not "); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "NVRAM : %spresent\n", - (cc->nvr == TRUE)?"":"not "); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "SmartROM : %sabled\n", - (bt->srom == TRUE)?"dis":"en"); - len += size; - pos = begin + len; - size = sprintf(buffer + len, "Alarm : %s\n", - (bt->alrm == TRUE)?"on":"off"); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - - if(SD(HBA_ptr)->do_latency == FALSE) { - - cmnd[0] = LOG_SENSE; - cmnd[1] = 0; - cmnd[2] = 0x32 + (3<<6); - cmnd[3] = 0; - cmnd[4] = 0; - cmnd[5] = 0; - cmnd[6] = 0; - cmnd[7] = 0x01; - cmnd[8] = 0x44; - cmnd[9] = 0; - - scmd->sr_cmd_len = 10; - scmd->sr_data_direction = SCSI_DATA_READ; - - /* - * Do the command and wait for it to finish. - */ - scsi_wait_req (scmd, cmnd, buff2, 0x144, - 1 * HZ, 1); - - swap_statistics(buff2); - rhcs = (hst_cmd_stat *)(buff2 + 0x2c); - whcs = (hst_cmd_stat *)(buff2 + 0x8c); - - for (x = 0; x <= 11; x++) { - SD(HBA_ptr)->reads[x] += rhcs->sizes[x]; - SD(HBA_ptr)->writes[x] += whcs->sizes[x]; - SD(HBA_ptr)->reads[12] += rhcs->sizes[x]; - SD(HBA_ptr)->writes[12] += whcs->sizes[x]; - } - size = sprintf(buffer + len, "Host<->Disk command statistics:\n" - " Reads: Writes:\n"); - len += size; - pos = begin + len; - for (x = 0; x <= 10; x++) { - size = sprintf(buffer+len,"%5dk:%12u %12u\n", 1 << x, - SD(HBA_ptr)->reads[x], - SD(HBA_ptr)->writes[x]); - len += size; - pos = begin + len; - } - size = sprintf(buffer+len,">1024k:%12u %12u\n", - SD(HBA_ptr)->reads[11], - SD(HBA_ptr)->writes[11]); - len += size; - pos = begin + len; - size = sprintf(buffer+len,"Sum :%12u %12u\n", - SD(HBA_ptr)->reads[12], - SD(HBA_ptr)->writes[12]); - len += size; - pos = begin + len; - } - - scsi_release_request(scmd); - scsi_free_host_dev(SDev); - } - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - - if(SD(HBA_ptr)->do_latency == TRUE) { - int factor = 1024/HZ; - size = sprintf(buffer + len, "Host Latency Command Statistics:\n" - "Current timer resolution: %2dms\n" - " Reads: Min:(ms) Max:(ms) Ave:(ms)\n", - factor); - len += size; - pos = begin + len; - for (x = 0; x <= 10; x++) { - size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", - 1 << x, - SD(HBA_ptr)->reads_lat[x][0], - (SD(HBA_ptr)->reads_lat[x][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->reads_lat[x][1] * factor), - SD(HBA_ptr)->reads_lat[x][2] * factor, - SD(HBA_ptr)->reads_lat[x][3] * factor / - ((SD(HBA_ptr)->reads_lat[x][0]) - ? SD(HBA_ptr)->reads_lat[x][0]:1)); - len += size; - pos = begin + len; - } - size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n", - SD(HBA_ptr)->reads_lat[11][0], - (SD(HBA_ptr)->reads_lat[11][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->reads_lat[11][1] * factor), - SD(HBA_ptr)->reads_lat[11][2] * factor, - SD(HBA_ptr)->reads_lat[11][3] * factor / - ((SD(HBA_ptr)->reads_lat[x][0]) - ? SD(HBA_ptr)->reads_lat[x][0]:1)); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - - size = sprintf(buffer + len, - " Writes: Min:(ms) Max:(ms) Ave:(ms)\n"); - len += size; - pos = begin + len; - for (x = 0; x <= 10; x++) { - size = sprintf(buffer+len,"%5dk:%12u %12u %12u %12u\n", - 1 << x, - SD(HBA_ptr)->writes_lat[x][0], - (SD(HBA_ptr)->writes_lat[x][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), - SD(HBA_ptr)->writes_lat[x][2] * factor, - SD(HBA_ptr)->writes_lat[x][3] * factor / - ((SD(HBA_ptr)->writes_lat[x][0]) - ? SD(HBA_ptr)->writes_lat[x][0]:1)); - len += size; - pos = begin + len; - } - size = sprintf(buffer+len,">1024k:%12u %12u %12u %12u\n", - SD(HBA_ptr)->writes_lat[11][0], - (SD(HBA_ptr)->writes_lat[11][1] == 0xffffffff) - ? 0:(SD(HBA_ptr)->writes_lat[x][1] * factor), - SD(HBA_ptr)->writes_lat[11][2] * factor, - SD(HBA_ptr)->writes_lat[11][3] * factor / - ((SD(HBA_ptr)->writes_lat[x][0]) - ? SD(HBA_ptr)->writes_lat[x][0]:1)); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - } - - size = sprintf(buffer+len,"Attached devices: %s\n", - (!list_empty(&HBA_ptr->my_devices))?"":"none"); - len += size; - pos = begin + len; - - list_for_each_entry(scd, &HBA_ptr->my_devices, siblings) { - proc_print_scsidevice(scd, buffer, &size, len); - len += size; - pos = begin + len; - - if (pos < offset) { - len = 0; - begin = pos; - } - if (pos > offset + length) - goto stop_output; - } - - stop_output: - DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); - *start=buffer+(offset-begin); /* Start of wanted data */ - len-=(offset-begin); /* Start slop */ - if(len>length) - len = length; /* Ending slop */ - DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); - - return (len); -} - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * tab-width: 8 - * End: - */ diff -Nru a/drivers/scsi/eata_dma_proc.h b/drivers/scsi/eata_dma_proc.h --- a/drivers/scsi/eata_dma_proc.h Tue Feb 18 01:03:47 2003 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,260 +0,0 @@ - -struct lun_map { - __u8 id:5, - chan:3; - __u8 lun; -}; - -typedef struct emul_pp { - __u8 p_code:6, - null:1, - p_save:1; - __u8 p_length; - __u16 cylinder; - __u8 heads; - __u8 sectors; - __u8 null2; - __u8 s_lunmap:4, - ems:1; - __u16 drive_type; /* In Little Endian ! */ - struct lun_map lunmap[4]; -}emulpp; - - -/* Log Sense pages */ - -typedef struct log_sheader { - __u8 page_code, - reserved; - __u16 length; -}logsh; - - -/* Log Sense Statistics */ - -typedef struct read_command_statistics { - __u16 code; /* 0x01 */ - __u8 flags; - __u8 length; /* 0x24 */ - __u32 h_commands, - uncached, - la_cmds, - la_blks, - la_hits, - missed, - hits, - seq_la_blks, - seq_la_hits; -}r_cmd_stat; - -typedef struct write_command_statistics { - __u16 code; /* 0x03 */ - __u8 flags; - __u8 length; /* 0x28 */ - __u32 h_commands, - uncached, - thru, - bypass, - soft_err, - hits, - b_idle, - b_activ, - b_blks, - b_blks_clean; -}w_cmd_stat; - -typedef struct host_command_statistics { - __u16 code; /* 0x02, 0x04 */ - __u8 flags; - __u8 length; /* 0x30 */ - __u32 sizes[12]; -}hst_cmd_stat; - -typedef struct physical_command_statistics { - __u16 code; /* 0x06, 0x07 */ - __u8 flags; - __u8 length; /* 0x34 */ - __u32 sizes[13]; -}phy_cmd_stat; - -typedef struct misc_device_statistics { - __u16 code; /* 0x05 */ - __u8 flags; - __u8 length; /* 0x10 */ - __u32 disconnect, - pass_thru, - sg_commands, - stripe_boundary_crosses; -}msc_stats; - -/* Configuration Pages */ - -typedef struct controller_configuration { - __u16 code; /* 0x01 */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 intt:1, - sec:1, - csh:1, - key:1, - tmr:1, - srs:1, - nvr:1; - __u8 interrupt; -}coco; - -typedef struct controller_hardware_errors { - __u16 code; /* 0x02 */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 unused:1, - per:1; - __u8 interrupt; -}coher; - -typedef struct memory_map { - __u16 code; /* 0x03, 0x04 */ - __u8 flags; - __u8 length; /* 0x04 */ - __u32 memory_map; -}mema; - -typedef struct scsi_transfer { - __u16 code; /* 0x05 */ - __u8 flags; - __u8 length; /* 0x04 */ - __u8 offset, - period; - __u16 speed; -}scsitrans; - -typedef struct scsi_modes { - __u16 code; /* 0x06 */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 que:1, - cdis:1, - wtru:1, - dasd:1, - ncr:1, - awre:1; - __u8 reserved; -}scsimod; - -typedef struct host_bus { - __u16 code; /* 0x07 */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 speed:6, - pci:1, - eisa:1; - __u8 reserved; -}hobu; - -typedef struct scsi_bus { - __u16 code; /* 0x08 */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 speed:4, - res:1, - ext:1, - wide:1, - dif:1; - __u8 busnum; -}scbu; - -typedef struct board_type { - __u16 code; /* 0x09 */ - __u8 flags; - __u8 length; /* 0x04 */ - __u8 unused:1, - cmi:1, - dmi:1, - cm4k:1, - cm4:1, - dm4k:1, - dm4:1, - hba:1; - __u8 cpu_type, - cpu_speed; - __u8 sx1:1, - sx2:1, - unused2:4, - alrm:1, - srom:1; -}boty; - -typedef struct memory_config { - __u16 code; /* 0x0a */ - __u8 flags; - __u8 length; /* 0x04 */ - __u8 banksize[4]; -}memco; - -typedef struct firmware_info { - __u16 code; /* 0x0b */ - __u8 flags; - __u8 length; /* 0x04 */ - __u8 dnld:1, - bs528:1, - fmt:1, - fw528:1; - __u8 unused1, - fw_type, - unused; -}firm; - -typedef struct subsystem_info { - __u16 code; /* 0x0c */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 shlf:1, - swap:1, - noss:1; - __u8 reserved; -}subinf; - -typedef struct per_channel_info { - __u16 code; /* 0x0d */ - __u8 flags; - __u8 length; /* 0x02 */ - __u8 channel; - __u8 shlf:1, - swap:1, - noss:1, - srs:1, - que:1, - ext:1, - wide:1, - diff:1; -}pcinf; - -typedef struct array_limits { - __u16 code; /* 0x0e */ - __u8 flags; - __u8 length; /* 0x04 */ - __u8 max_groups, - raid0_drv, - raid35_drv, - unused; -}arrlim; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: nil - * tab-width: 8 - * End: - */ - diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c --- a/drivers/scsi/fdomain.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/fdomain.c Tue Feb 18 01:03:47 2003 @@ -960,7 +960,7 @@ return 0; shpnt->irq = interrupt_level; shpnt->io_port = port_base; - scsi_set_pci_device(shpnt, pdev); + scsi_set_device(shpnt, &pdev->dev); shpnt->n_io_port = 0x10; print_banner( shpnt ); diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h --- a/drivers/scsi/hosts.h Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/hosts.h Tue Feb 18 01:03:47 2003 @@ -27,7 +27,6 @@ #include #include #include -#include struct scsi_host_cmd_pool; @@ -533,13 +532,6 @@ { return shost->host_gendev; } - -static inline void scsi_set_pci_device(struct Scsi_Host *shost, - struct pci_dev *pdev) -{ - scsi_set_device(shost, &pdev->dev); -} - /* * Prototypes for functions/data in scsi_scan.c diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c --- a/drivers/scsi/ips.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/ips.c Tue Feb 18 01:03:47 2003 @@ -6744,7 +6744,7 @@ kfree(oldha); ips_sh[index] = sh; ips_ha[index] = ha; - scsi_set_pci_device(sh, ha->pcidev); + scsi_set_device(sh, &ha->pcidev->dev); /* Store away needed values for later use */ sh->io_port = ha->io_addr; diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c --- a/drivers/scsi/megaraid.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/megaraid.c Tue Feb 18 01:03:47 2003 @@ -2963,7 +2963,7 @@ */ host->max_sectors = 1024; - scsi_set_pci_device(host, pdev); + scsi_set_device(host, &pdev->dev); megaCfg = (mega_host_config *) host->hostdata; memset (megaCfg, 0, sizeof (mega_host_config)); diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c --- a/drivers/scsi/nsp32.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/nsp32.c Tue Feb 18 01:03:47 2003 @@ -1661,7 +1661,7 @@ host->unique_id = data->BaseAddress; host->n_io_port = data->NumAddress; host->base = data->MmioAddress; - scsi_set_pci_device(host, data->Pci); + scsi_set_device(host, &data->Pci->dev); data->Host = host; spin_lock_init(&(data->Lock)); diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c --- a/drivers/scsi/pci2000.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/pci2000.c Tue Feb 18 01:03:47 2003 @@ -707,7 +707,7 @@ goto unregister; } - scsi_set_pci_device(pshost, pdev); + scsi_set_device(pshost, &pdev->dev); pshost->irq = pdev->irq; setirq = 1; padapter->irqOwned = 0; diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c --- a/drivers/scsi/pci2220i.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/pci2220i.c Tue Feb 18 01:03:47 2003 @@ -2549,7 +2549,7 @@ if ( GetRegs (pshost, FALSE, pcidev) ) goto unregister; - scsi_set_pci_device(pshost, pcidev); + scsi_set_device(pshost, &pcidev->dev); pshost->max_id = padapter->numberOfDrives; for ( z = 0; z < padapter->numberOfDrives; z++ ) { diff -Nru a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c --- a/drivers/scsi/pcmcia/aha152x_stub.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/pcmcia/aha152x_stub.c Tue Feb 18 01:03:47 2003 @@ -408,7 +408,7 @@ if (link->state & DEV_CONFIG) { Scsi_Cmnd tmp; CardServices(RequestConfiguration, link->handle, &link->conf); - tmp.host = info->host; + tmp.device->host = info->host; aha152x_host_reset(&tmp); } break; diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c --- a/drivers/scsi/pcmcia/nsp_cs.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/pcmcia/nsp_cs.c Tue Feb 18 01:03:48 2003 @@ -325,9 +325,9 @@ static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int host_id = SCpnt->host->this_id; - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; + unsigned int host_id = SCpnt->device->host->this_id; + unsigned int base = SCpnt->device->host->io_port; + unsigned char target = SCpnt->device->id; int time_out; unsigned char phase, arbit; @@ -405,7 +405,7 @@ */ static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned char target = SCpnt->target; + unsigned char target = SCpnt->device->id; // unsigned char lun = SCpnt->lun; sync_data *sync = &(data->Sync[target]); struct nsp_sync_table *sync_table; @@ -462,7 +462,7 @@ */ static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; //DEBUG(0, "%s: in SCpnt=0x%p, time=%d\n", __FUNCTION__, SCpnt, time); data->TimerCount = time; @@ -474,7 +474,7 @@ */ static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned char reg; int time_out; @@ -503,7 +503,7 @@ unsigned char current_phase, unsigned char mask) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; int time_out; unsigned char phase, i_src; @@ -536,7 +536,7 @@ */ static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; char *buf = data->MsgBuffer; int len = MIN(MSGBUF_SIZE, data->MsgLen); int ptr; @@ -606,7 +606,7 @@ */ static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned char reg; //DEBUG(0, "%s:\n", __FUNCTION__); @@ -626,7 +626,7 @@ */ static int nsp_fifo_count(Scsi_Cmnd *SCpnt) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned int count; unsigned int l, m, h, dummy; @@ -653,8 +653,8 @@ */ static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; - unsigned long mmio_base = SCpnt->host->base; + unsigned int base = SCpnt->device->host->io_port; + unsigned long mmio_base = SCpnt->device->host->base; long time_out; int ocount, res; unsigned char stat, fifo_stat; @@ -746,8 +746,8 @@ */ static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; - unsigned long mmio_base = SCpnt->host->base; + unsigned int base = SCpnt->device->host->io_port; + unsigned long mmio_base = SCpnt->device->host->base; int time_out; int ocount, res; unsigned char stat; @@ -838,8 +838,8 @@ */ static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; - unsigned char target = SCpnt->target; + unsigned int base = SCpnt->device->host->io_port; + unsigned char target = SCpnt->device->id; // unsigned char lun = SCpnt->lun; sync_data *sync = &(data->Sync[target]); @@ -944,8 +944,8 @@ return; } else { tmpSC = data->CurrentSC; - target = tmpSC->target; - lun = tmpSC->lun; + target = tmpSC->device->id; + lun = tmpSC->device->lun; sync_neg = &(data->Sync[target].SyncNegotiation); } @@ -1425,7 +1425,7 @@ static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt) { nsp_hw_data *data = &nsp_data; - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; int i; DEBUG(0, "%s: SCpnt=0x%p base=0x%x\n", __FUNCTION__, SCpnt, base); @@ -1960,7 +1960,7 @@ } info->stop = 0; - tmp.host = info->host; + tmp.device->host = info->host; nsp_eh_host_reset(&tmp); nsp_eh_bus_reset(&tmp); diff -Nru a/drivers/scsi/pcmcia/nsp_message.c b/drivers/scsi/pcmcia/nsp_message.c --- a/drivers/scsi/pcmcia/nsp_message.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/pcmcia/nsp_message.c Tue Feb 18 01:03:47 2003 @@ -10,7 +10,7 @@ static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data) { - unsigned int base = SCpnt->host->io_port; + unsigned int base = SCpnt->device->host->io_port; unsigned char data_reg, control_reg; int ret, len; diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c --- a/drivers/scsi/ppa.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/ppa.c Tue Feb 18 01:03:47 2003 @@ -106,7 +106,7 @@ int ppa_detect(Scsi_Host_Template * host) { - struct Scsi_Host *hreg; + struct Scsi_Host *hreg = NULL; int ports; int i, nhosts, try_again; struct parport *pb; diff -Nru a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c --- a/drivers/scsi/qla1280.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/qla1280.c Tue Feb 18 01:03:48 2003 @@ -814,7 +814,7 @@ goto error; } - scsi_set_pci_device(host, pdev); + scsi_set_device(host, &pdev->dev); ha = (struct scsi_qla_host *)host->hostdata; /* Clear our data area */ memset(ha, 0, sizeof(struct scsi_qla_host)); diff -Nru a/drivers/scsi/qlogicfc.c b/drivers/scsi/qlogicfc.c --- a/drivers/scsi/qlogicfc.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/qlogicfc.c Tue Feb 18 01:03:47 2003 @@ -731,7 +731,7 @@ printk("qlogicfc%d : could not register host.\n", hosts); continue; } - scsi_set_pci_device(host, pdev); + scsi_set_device(host, &pdev->dev); host->max_id = QLOGICFC_MAX_ID + 1; host->max_lun = QLOGICFC_MAX_LUN; hostdata = (struct isp2x00_hostdata *) host->hostdata; diff -Nru a/drivers/scsi/qlogicisp.c b/drivers/scsi/qlogicisp.c --- a/drivers/scsi/qlogicisp.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/qlogicisp.c Tue Feb 18 01:03:48 2003 @@ -685,7 +685,7 @@ memset(hostdata, 0, sizeof(struct isp1020_hostdata)); hostdata->pci_dev = pdev; - scsi_set_pci_device(host, pdev); + scsi_set_device(host, &pdev->dev); if (isp1020_init(host)) goto fail_and_unregister; diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c --- a/drivers/scsi/scsi.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/scsi.c Tue Feb 18 01:03:47 2003 @@ -171,30 +171,6 @@ #endif /* - * Issue a command and wait for it to complete - */ - -static void scsi_wait_done(Scsi_Cmnd * SCpnt) -{ - struct request *req = SCpnt->request; - struct request_queue *q = SCpnt->device->request_queue; - unsigned long flags; - - ASSERT_LOCK(q->queue_lock, 0); - req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ - - spin_lock_irqsave(q->queue_lock, flags); - - if(blk_rq_tagged(req)) - blk_queue_end_tag(q, req); - - spin_unlock_irqrestore(q->queue_lock, flags); - - if (req->waiting) - complete(req->waiting); -} - -/* * Function: scsi_allocate_request * * Purpose: Allocate a request descriptor. @@ -263,87 +239,6 @@ kfree(req); } -/* - * Function: scsi_mlqueue_insert() - * - * Purpose: Insert a command in the midlevel queue. - * - * Arguments: cmd - command that we are adding to queue. - * reason - why we are inserting command to queue. - * - * Lock status: Assumed that lock is not held upon entry. - * - * Returns: Nothing. - * - * Notes: We do this for one of two cases. Either the host is busy - * and it cannot accept any more commands for the time being, - * or the device returned QUEUE_FULL and can accept no more - * commands. - * Notes: This could be called either from an interrupt context or a - * normal process context. - */ -static int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason) -{ - struct Scsi_Host *host = cmd->device->host; - struct scsi_device *device = cmd->device; - - SCSI_LOG_MLQUEUE(1, - printk("Inserting command %p into mlqueue\n", cmd)); - - /* - * We are inserting the command into the ml queue. First, we - * cancel the timer, so it doesn't time out. - */ - scsi_delete_timer(cmd); - - /* - * Next, set the appropriate busy bit for the device/host. - * - * If the host/device isn't busy, assume that something actually - * completed, and that we should be able to queue a command now. - * - * Note that the prior mid-layer assumption that any host could - * always queue at least one command is now broken. The mid-layer - * will implement a user specifiable stall (see - * scsi_host.max_host_blocked and scsi_device.max_device_blocked) - * if a command is requeued with no other commands outstanding - * either for the device or for the host. - */ - if (reason == SCSI_MLQUEUE_HOST_BUSY) { - host->host_blocked = host->max_host_blocked; - } else { - device->device_blocked = device->max_device_blocked; - } - - /* - * Register the fact that we own the thing for now. - */ - cmd->state = SCSI_STATE_MLQUEUE; - cmd->owner = SCSI_OWNER_MIDLEVEL; - cmd->bh_next = NULL; - - /* - * Decrement the counters, since these commands are no longer - * active on the host/device. - */ - scsi_host_busy_dec_and_test(host, device); - - /* - * Insert this command at the head of the queue for it's device. - * It will go before all other commands that are already in the queue. - * - * NOTE: there is magic here about the way the queue is - * plugged if we have no outstanding commands. - * scsi_insert_special_cmd eventually calls - * blk_queue_insert(). Although this *doesn't* plug the - * queue, it does call the request function. The SCSI request - * function detects the blocked condition and plugs the queue - * appropriately. - */ - scsi_insert_special_cmd(cmd, 1); - return 0; -} - struct scsi_host_cmd_pool { kmem_cache_t *slab; unsigned int users; @@ -621,7 +516,7 @@ rtn = host->hostt->queuecommand(SCpnt, scsi_done); spin_unlock_irqrestore(host->host_lock, flags); if (rtn != 0) { - scsi_mlqueue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY); + scsi_queue_insert(SCpnt, rtn == SCSI_MLQUEUE_DEVICE_BUSY ? rtn : SCSI_MLQUEUE_HOST_BUSY); SCSI_LOG_MLQUEUE(3, printk("queuecommand : request rejected\n")); } @@ -659,128 +554,6 @@ return rtn; } -void scsi_wait_req (Scsi_Request * SRpnt, const void *cmnd , - void *buffer, unsigned bufflen, - int timeout, int retries) -{ - DECLARE_COMPLETION(wait); - - SRpnt->sr_request->waiting = &wait; - SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; - scsi_do_req (SRpnt, (void *) cmnd, - buffer, bufflen, scsi_wait_done, timeout, retries); - generic_unplug_device(SRpnt->sr_device->request_queue); - wait_for_completion(&wait); - SRpnt->sr_request->waiting = NULL; - if( SRpnt->sr_command != NULL ) - { - scsi_put_command(SRpnt->sr_command); - SRpnt->sr_command = NULL; - } - -} - -/* - * Function: scsi_do_req - * - * Purpose: Queue a SCSI request - * - * Arguments: SRpnt - command descriptor. - * cmnd - actual SCSI command to be performed. - * buffer - data buffer. - * bufflen - size of data buffer. - * done - completion function to be run. - * timeout - how long to let it run before timeout. - * retries - number of retries we allow. - * - * Lock status: With the new queueing code, this is SMP-safe, and no locks - * need be held upon entry. The old queueing code the lock was - * assumed to be held upon entry. - * - * Returns: Nothing. - * - * Notes: Prior to the new queue code, this function was not SMP-safe. - * Also, this function is now only used for queueing requests - * for things like ioctls and character device requests - this - * is because we essentially just inject a request into the - * queue for the device. Normal block device handling manipulates - * the queue directly. - */ -void scsi_do_req(Scsi_Request * SRpnt, const void *cmnd, - void *buffer, unsigned bufflen, void (*done) (Scsi_Cmnd *), - int timeout, int retries) -{ - Scsi_Device * SDpnt = SRpnt->sr_device; - struct Scsi_Host *host = SDpnt->host; - - ASSERT_LOCK(host->host_lock, 0); - - SCSI_LOG_MLQUEUE(4, - { - int i; - int size = COMMAND_SIZE(((const unsigned char *)cmnd)[0]); - printk("scsi_do_req (host = %d, channel = %d target = %d, " - "buffer =%p, bufflen = %d, done = %p, timeout = %d, " - "retries = %d)\n" - "command : ", host->host_no, SDpnt->channel, SDpnt->id, buffer, - bufflen, done, timeout, retries); - for (i = 0; i < size; ++i) - printk("%02x ", ((unsigned char *) cmnd)[i]); - printk("\n"); - }); - - if (!host) { - panic("Invalid or not present host.\n"); - } - - /* - * If the upper level driver is reusing these things, then - * we should release the low-level block now. Another one will - * be allocated later when this request is getting queued. - */ - if( SRpnt->sr_command != NULL ) - { - scsi_put_command(SRpnt->sr_command); - SRpnt->sr_command = NULL; - } - - /* - * We must prevent reentrancy to the lowlevel host driver. This prevents - * it - we enter a loop until the host we want to talk to is not busy. - * Race conditions are prevented, as interrupts are disabled in between the - * time we check for the host being not busy, and the time we mark it busy - * ourselves. - */ - - - /* - * Our own function scsi_done (which marks the host as not busy, disables - * the timeout counter, etc) will be called by us or by the - * scsi_hosts[host].queuecommand() function needs to also call - * the completion function for the high level driver. - */ - - memcpy((void *) SRpnt->sr_cmnd, (const void *) cmnd, - sizeof(SRpnt->sr_cmnd)); - SRpnt->sr_bufflen = bufflen; - SRpnt->sr_buffer = buffer; - SRpnt->sr_allowed = retries; - SRpnt->sr_done = done; - SRpnt->sr_timeout_per_command = timeout; - - if (SRpnt->sr_cmd_len == 0) - SRpnt->sr_cmd_len = COMMAND_SIZE(SRpnt->sr_cmnd[0]); - - /* - * At this point, we merely set up the command, stick it in the normal - * request queue, and return. Eventually that request will come to the - * top of the list, and will be dispatched. - */ - scsi_insert_special_req(SRpnt, 0); - - SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_do_req()\n")); -} - /* * Function: scsi_init_cmd_from_req * @@ -998,7 +771,7 @@ */ SCSI_LOG_MLCOMPLETE(3, printk("Command rejected as device queue full, put on ml queue %p\n", SCpnt)); - scsi_mlqueue_insert(SCpnt, SCSI_MLQUEUE_DEVICE_BUSY); + scsi_queue_insert(SCpnt, SCSI_MLQUEUE_DEVICE_BUSY); break; default: /* diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h --- a/drivers/scsi/scsi.h Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/scsi.h Tue Feb 18 01:03:47 2003 @@ -433,12 +433,11 @@ */ extern int scsi_maybe_unblock_host(Scsi_Device * SDpnt); extern void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt); -extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int); extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors, int block_sectors); -extern void scsi_queue_next_request(request_queue_t * q, Scsi_Cmnd * SCpnt); -extern int scsi_prep_fn(struct request_queue *q, struct request *req); -extern void scsi_request_fn(request_queue_t * q); +extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); +extern request_queue_t *scsi_alloc_queue(struct Scsi_Host *shost); +extern void scsi_free_queue(request_queue_t *q); extern int scsi_init_queue(void); extern void scsi_exit_queue(void); diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c --- a/drivers/scsi/scsi_lib.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/scsi_lib.c Tue Feb 18 01:03:47 2003 @@ -14,6 +14,7 @@ #include #include #include +#include #include "scsi.h" #include "hosts.h" @@ -37,11 +38,11 @@ /* - * Function: scsi_insert_special_cmd() + * Function: scsi_insert_special_req() * - * Purpose: Insert pre-formed command into request queue. + * Purpose: Insert pre-formed request into request queue. * - * Arguments: cmd - command that is ready to be queued. + * Arguments: sreq - request that is ready to be queued. * at_head - boolean. True if we should insert at head * of queue, false if we should insert at tail. * @@ -56,46 +57,195 @@ * for now), and then call the queue request function to actually * process it. */ -int scsi_insert_special_cmd(struct scsi_cmnd *cmd, int at_head) +int scsi_insert_special_req(struct scsi_request *sreq, int at_head) { - blk_insert_request(cmd->device->request_queue, cmd->request, - at_head, cmd); + /* + * Because users of this function are apt to reuse requests with no + * modification, we have to sanitise the request flags here + */ + sreq->sr_request->flags &= ~REQ_DONTPREP; + blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, + at_head, sreq); return 0; } /* - * Function: scsi_insert_special_req() + * Function: scsi_queue_insert() * - * Purpose: Insert pre-formed request into request queue. + * Purpose: Insert a command in the midlevel queue. * - * Arguments: sreq - request that is ready to be queued. - * at_head - boolean. True if we should insert at head - * of queue, false if we should insert at tail. + * Arguments: cmd - command that we are adding to queue. + * reason - why we are inserting command to queue. * * Lock status: Assumed that lock is not held upon entry. * - * Returns: Nothing + * Returns: Nothing. * - * Notes: This function is called from character device and from - * ioctl types of functions where the caller knows exactly - * what SCSI command needs to be issued. The idea is that - * we merely inject the command into the queue (at the head - * for now), and then call the queue request function to actually - * process it. + * Notes: We do this for one of two cases. Either the host is busy + * and it cannot accept any more commands for the time being, + * or the device returned QUEUE_FULL and can accept no more + * commands. + * Notes: This could be called either from an interrupt context or a + * normal process context. */ -int scsi_insert_special_req(struct scsi_request *sreq, int at_head) +int scsi_queue_insert(struct scsi_cmnd *cmd, int reason) { + struct Scsi_Host *host = cmd->device->host; + struct scsi_device *device = cmd->device; + + SCSI_LOG_MLQUEUE(1, + printk("Inserting command %p into mlqueue\n", cmd)); + /* - * Because users of this function are apt to reuse requests with no - * modification, we have to sanitise the request flags here + * We are inserting the command into the ml queue. First, we + * cancel the timer, so it doesn't time out. */ - sreq->sr_request->flags &= ~REQ_DONTPREP; - blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request, - at_head, sreq); + scsi_delete_timer(cmd); + + /* + * Next, set the appropriate busy bit for the device/host. + * + * If the host/device isn't busy, assume that something actually + * completed, and that we should be able to queue a command now. + * + * Note that the prior mid-layer assumption that any host could + * always queue at least one command is now broken. The mid-layer + * will implement a user specifiable stall (see + * scsi_host.max_host_blocked and scsi_device.max_device_blocked) + * if a command is requeued with no other commands outstanding + * either for the device or for the host. + */ + if (reason == SCSI_MLQUEUE_HOST_BUSY) + host->host_blocked = host->max_host_blocked; + else + device->device_blocked = device->max_device_blocked; + + /* + * Register the fact that we own the thing for now. + */ + cmd->state = SCSI_STATE_MLQUEUE; + cmd->owner = SCSI_OWNER_MIDLEVEL; + cmd->bh_next = NULL; + + /* + * Decrement the counters, since these commands are no longer + * active on the host/device. + */ + scsi_host_busy_dec_and_test(host, device); + + /* + * Insert this command at the head of the queue for it's device. + * It will go before all other commands that are already in the queue. + * + * NOTE: there is magic here about the way the queue is plugged if + * we have no outstanding commands. + * + * Although this *doesn't* plug the queue, it does call the request + * function. The SCSI request function detects the blocked condition + * and plugs the queue appropriately. + */ + blk_insert_request(device->request_queue, cmd->request, 1, cmd); return 0; } /* + * Function: scsi_do_req + * + * Purpose: Queue a SCSI request + * + * Arguments: sreq - command descriptor. + * cmnd - actual SCSI command to be performed. + * buffer - data buffer. + * bufflen - size of data buffer. + * done - completion function to be run. + * timeout - how long to let it run before timeout. + * retries - number of retries we allow. + * + * Lock status: No locks held upon entry. + * + * Returns: Nothing. + * + * Notes: This function is only used for queueing requests for things + * like ioctls and character device requests - this is because + * we essentially just inject a request into the queue for the + * device. + */ +void scsi_do_req(struct scsi_request *sreq, const void *cmnd, + void *buffer, unsigned bufflen, + void (*done)(struct scsi_cmnd *), + int timeout, int retries) +{ + /* + * If the upper level driver is reusing these things, then + * we should release the low-level block now. Another one will + * be allocated later when this request is getting queued. + */ + if (sreq->sr_command) { + scsi_put_command(sreq->sr_command); + sreq->sr_command = NULL; + } + + /* + * Our own function scsi_done (which marks the host as not busy, + * disables the timeout counter, etc) will be called by us or by the + * scsi_hosts[host].queuecommand() function needs to also call + * the completion function for the high level driver. + */ + memcpy(sreq->sr_cmnd, cmnd, sizeof(sreq->sr_cmnd)); + sreq->sr_bufflen = bufflen; + sreq->sr_buffer = buffer; + sreq->sr_allowed = retries; + sreq->sr_done = done; + sreq->sr_timeout_per_command = timeout; + + if (sreq->sr_cmd_len == 0) + sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]); + + /* + * At this point, we merely set up the command, stick it in the normal + * request queue, and return. Eventually that request will come to the + * top of the list, and will be dispatched. + */ + scsi_insert_special_req(sreq, 0); +} + +static void scsi_wait_done(struct scsi_cmnd *cmd) +{ + struct request *req = cmd->request; + struct request_queue *q = cmd->device->request_queue; + unsigned long flags; + + req->rq_status = RQ_SCSI_DONE; /* Busy, but indicate request done */ + + spin_lock_irqsave(q->queue_lock, flags); + if (blk_rq_tagged(req)) + blk_queue_end_tag(q, req); + spin_unlock_irqrestore(q->queue_lock, flags); + + if (req->waiting) + complete(req->waiting); +} + +void scsi_wait_req(struct scsi_request *sreq, const void *cmnd, void *buffer, + unsigned bufflen, int timeout, int retries) +{ + DECLARE_COMPLETION(wait); + + sreq->sr_request->waiting = &wait; + sreq->sr_request->rq_status = RQ_SCSI_BUSY; + scsi_do_req(sreq, cmnd, buffer, bufflen, scsi_wait_done, + timeout, retries); + generic_unplug_device(sreq->sr_device->request_queue); + wait_for_completion(&wait); + sreq->sr_request->waiting = NULL; + + if (sreq->sr_command) { + scsi_put_command(sreq->sr_command); + sreq->sr_command = NULL; + } +} + +/* * Function: scsi_init_cmd_errh() * * Purpose: Initialize cmd fields related to error handling. @@ -203,7 +353,7 @@ * permutations grows as 2**N, and if too many more special cases * get added, we start to get screwed. */ -void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd) +static void scsi_queue_next_request(request_queue_t *q, struct scsi_cmnd *cmd) { struct scsi_device *sdev, *sdev2; struct Scsi_Host *shost; @@ -791,7 +941,7 @@ return 0; } -int scsi_prep_fn(struct request_queue *q, struct request *req) +static int scsi_prep_fn(struct request_queue *q, struct request *req) { struct Scsi_Device_Template *sdt; struct scsi_device *sdev = q->queuedata; @@ -902,7 +1052,7 @@ * * Lock status: IO request lock assumed to be held when called. */ -void scsi_request_fn(request_queue_t *q) +static void scsi_request_fn(request_queue_t *q) { struct scsi_device *sdev = q->queuedata; struct Scsi_Host *shost = sdev->host; @@ -1045,6 +1195,62 @@ */ spin_lock_irq(q->queue_lock); } +} + +u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) +{ + if (shost->highmem_io) { + struct device *host_dev = scsi_get_device(shost); + + if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask) + return *host_dev->dma_mask; + + /* + * Platforms with virtual-DMA translation + * hardware have no practical limit. + */ + return BLK_BOUNCE_ANY; + } else if (shost->unchecked_isa_dma) + return BLK_BOUNCE_ISA; + + return BLK_BOUNCE_HIGH; +} + +request_queue_t *scsi_alloc_queue(struct Scsi_Host *shost) +{ + request_queue_t *q; + + q = kmalloc(sizeof(*q), GFP_ATOMIC); + if (!q) + return NULL; + memset(q, 0, sizeof(*q)); + + if (!shost->max_sectors) { + /* + * Driver imposes no hard sector transfer limit. + * start at machine infinity initially. + */ + shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS; + } + + blk_init_queue(q, scsi_request_fn, shost->host_lock); + blk_queue_prep_rq(q, scsi_prep_fn); + + blk_queue_max_hw_segments(q, shost->sg_tablesize); + blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); + blk_queue_max_sectors(q, shost->max_sectors); + blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); + + if (!shost->use_clustering) + clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); + + return q; +} + +void scsi_free_queue(request_queue_t *q) +{ + blk_cleanup_queue(q); + kfree(q); } /* diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c --- a/drivers/scsi/scsi_scan.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/scsi_scan.c Tue Feb 18 01:03:47 2003 @@ -364,62 +364,6 @@ printk("\n"); } -u64 scsi_calculate_bounce_limit(struct Scsi_Host *shost) -{ - if (shost->highmem_io) { - struct device *host_dev = scsi_get_device(shost); - - if (PCI_DMA_BUS_IS_PHYS && host_dev && host_dev->dma_mask) - return *host_dev->dma_mask; - - /* - * Platforms with virtual-DMA translation - * hardware have no practical limit. - */ - return BLK_BOUNCE_ANY; - } else if (shost->unchecked_isa_dma) - return BLK_BOUNCE_ISA; - - return BLK_BOUNCE_HIGH; -} - -static request_queue_t *scsi_alloc_queue(struct Scsi_Host *shost) -{ - request_queue_t *q; - - q = kmalloc(sizeof(*q), GFP_ATOMIC); - if (!q) - return NULL; - memset(q, 0, sizeof(*q)); - - if (!shost->max_sectors) { - /* - * Driver imposes no hard sector transfer limit. - * start at machine infinity initially. - */ - shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS; - } - - blk_init_queue(q, scsi_request_fn, shost->host_lock); - blk_queue_prep_rq(q, scsi_prep_fn); - - blk_queue_max_hw_segments(q, shost->sg_tablesize); - blk_queue_max_phys_segments(q, MAX_PHYS_SEGMENTS); - blk_queue_max_sectors(q, shost->max_sectors); - blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); - - if (!shost->use_clustering) - clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); - - return q; -} - -static void scsi_free_queue(request_queue_t *q) -{ - blk_cleanup_queue(q); - kfree(q); -} - /** * scsi_alloc_sdev - allocate and setup a Scsi_Device * diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c --- a/drivers/scsi/sim710.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/sim710.c Tue Feb 18 01:03:47 2003 @@ -32,51 +32,19 @@ #include #include #include -#ifdef CONFIG_MCA #include -#endif -#ifdef CONFIG_EISA #include -#endif +#include #include "scsi.h" #include "hosts.h" #include "53c700.h" + /* Must be enough for both EISA and MCA */ #define MAX_SLOTS 8 static __u8 __initdata id_array[MAX_SLOTS] = { [0 ... MAX_SLOTS-1] = 7 }; -/* info is used to communicate global data across the driver register - * because the struct device_driver doesn't have any info fields. Sigh */ -struct sim710_info { - Scsi_Host_Template *tpnt; - int found; -}; - -static __initdata struct sim710_info sim710_global_info; - -#if defined(CONFIG_MCA) - -/* CARD ID 01BB and 01BA use the same pos values */ - -#define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \ - 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \ - 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \ - 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000 } - -#define MCA_01BB_IRQS { 3, 5, 11, 14 } - -/* CARD ID 004f */ - -#define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600 } - -#define MCA_004F_IRQS { 5, 9, 14 } - -#endif - -#ifdef MODULE - char *sim710; /* command line passed by insmod */ MODULE_AUTHOR("Richard Hirst"); @@ -85,8 +53,6 @@ MODULE_PARM(sim710, "s"); -#endif - #ifdef MODULE #define ARG_SEP ' ' #else @@ -118,12 +84,15 @@ } return 1; } - -#ifndef MODULE __setup("sim710=", param_setup); -#endif -__init int +static Scsi_Host_Template sim710_driver_template = { + .name = "LSI (Symbios) 710 MCA/EISA", + .proc_name = "sim710", + .this_id = 7, +}; + +static __devinit int sim710_probe_common(struct device *dev, unsigned long base_addr, int irq, int clock, int differential, int scsi_id) { @@ -154,7 +123,7 @@ hostdata->chip710 = 1; /* and register the chip */ - if((host = NCR_700_detect(sim710_global_info.tpnt, hostdata)) == NULL) { + if((host = NCR_700_detect(&sim710_driver_template, hostdata)) == NULL) { printk(KERN_ERR "sim710: No host detected; card configuration problem?\n"); goto out_release; } @@ -168,11 +137,9 @@ goto out_unregister; } - scsi_set_device(host, dev); + scsi_add_host(host, dev); hostdata->dev = dev; - sim710_global_info.found++; - return 0; out_unregister: @@ -185,10 +152,37 @@ return -ENODEV; } +static __devexit int +sim710_device_remove(struct device *dev) +{ + struct Scsi_Host *host = to_scsi_host(dev); + struct NCR_700_Host_Parameters *hostdata = + (struct NCR_700_Host_Parameters *)host->hostdata[0]; + + scsi_remove_host(host); + NCR_700_release(host); + kfree(hostdata); + free_irq(host->irq, host); + return 0; +} + #ifdef CONFIG_MCA + +/* CARD ID 01BB and 01BA use the same pos values */ +#define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \ + 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \ + 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \ + 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000 } + +#define MCA_01BB_IRQS { 3, 5, 11, 14 } + +/* CARD ID 004f */ +#define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600 } +#define MCA_004F_IRQS { 5, 9, 14 } + static short sim710_mca_id_table[] = { 0x01bb, 0x01ba, 0x004f, 0}; -__init int +static __init int sim710_mca_probe(struct device *dev) { struct mca_device *mca_dev = to_mca_device(dev); @@ -268,26 +262,27 @@ 0, id_array[slot]); } -struct mca_driver sim710_mca_driver = { - .id_table = sim710_mca_id_table, +static struct mca_driver sim710_mca_driver = { + .id_table = sim710_mca_id_table, .driver = { - .name = "sim710", - .bus = &mca_bus_type, - .probe = sim710_mca_probe, + .name = "sim710", + .bus = &mca_bus_type, + .probe = sim710_mca_probe, + .remove = __devexit_p(sim710_device_remove), }, }; #endif /* CONFIG_MCA */ #ifdef CONFIG_EISA -struct eisa_device_id sim710_eisa_ids[] = { +static struct eisa_device_id sim710_eisa_ids[] = { { "CPQ4410" }, { "CPQ4411" }, { "HWP0C80" }, { "" } }; -__init int +static __init int sim710_eisa_probe(struct device *dev) { struct eisa_device *edev = to_eisa_device(dev); @@ -307,7 +302,7 @@ #endif } else { eisa_irqs = eisa_cpq_irqs; - irq_index = inb(io_addr + 0xc88); + irq_index = inb(io_addr + 0xc88) & 0x07; } if(irq_index >= strlen(eisa_irqs)) { @@ -322,36 +317,18 @@ } struct eisa_driver sim710_eisa_driver = { - .id_table = sim710_eisa_ids, + .id_table = sim710_eisa_ids, .driver = { - .name = "sim710", - .probe = sim710_eisa_probe, - .remove = __devexit_p(sim710_device_remove), + .name = "sim710", + .probe = sim710_eisa_probe, + .remove = __devexit_p(sim710_device_remove), }, }; - #endif /* CONFIG_EISA */ - -int -sim710_release(struct Scsi_Host *host) +static int __init sim710_init(void) { - struct D700_Host_Parameters *hostdata = - (struct D700_Host_Parameters *)host->hostdata[0]; - - NCR_700_release(host); - kfree(hostdata); - free_irq(host->irq, host); - /* should do a refcount here and unregister the drivers when - * it reaches zero */ - return 1; -} - -int __init -sim710_detect(Scsi_Host_Template *tpnt) -{ - sim710_global_info.tpnt = tpnt; - sim710_global_info.found = 0; + int err = -ENODEV, err2; #ifdef MODULE if (sim710) @@ -359,22 +336,37 @@ #endif #ifdef CONFIG_MCA - if(MCA_bus) - mca_register_driver(&sim710_mca_driver); + if (MCA_bus) + err = mca_register_driver(&sim710_mca_driver); #endif #ifdef CONFIG_EISA - eisa_driver_register(&sim710_eisa_driver); + err2 = eisa_driver_register(&sim710_eisa_driver); + + /* + * The eise_driver_register return values are strange. I have + * no idea why we don't just use river_register directly anyway.. + */ + if (err2 == 1) + err2 = 0; #endif - return sim710_global_info.found; + + if (err < 0 || err2 < 0) + return (err < 0) ? err : err2; + return 0; } -static Scsi_Host_Template driver_template = { - .name = "LSI (Symbios) 710 MCA/EISA", - .proc_name = "sim710", - .detect = sim710_detect, - .release = sim710_release, - .this_id = 7, -}; +static void __exit sim710_exit(void) +{ +#ifdef CONFIG_MCA + if (MCA_bus) + mca_unregister_driver(&sim710_mca_driver); +#endif + +#ifdef CONFIG_EISA + eisa_driver_unregister(&sim710_eisa_driver); +#endif +} -#include "scsi_module.c" +module_init(sim710_init); +module_exit(sim710_exit); diff -Nru a/drivers/scsi/sym53c8xx.c b/drivers/scsi/sym53c8xx.c --- a/drivers/scsi/sym53c8xx.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/sym53c8xx.c Tue Feb 18 01:03:47 2003 @@ -5890,7 +5890,7 @@ instance->dma_channel = 0; instance->cmd_per_lun = MAX_TAGS; instance->can_queue = (MAX_START-4); - scsi_set_pci_device(instance, device->pdev); + scsi_set_device(instance, &device->pdev->dev); np->check_integrity = 0; diff -Nru a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c --- a/drivers/scsi/sym53c8xx_2/sym_glue.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c Tue Feb 18 01:03:48 2003 @@ -1876,7 +1876,7 @@ sym_name(np)); } else { - if (!pci_set_dma_mask(np->s.device, 0xffffffffUL)) + if (pci_set_dma_mask(np->s.device, 0xffffffffUL)) goto out_err32; } } @@ -2130,7 +2130,7 @@ SYM_UNLOCK_HCB(np, flags); - scsi_set_pci_device(instance, dev->pdev); + scsi_set_device(instance, &dev->pdev->dev); /* * Now let the generic SCSI driver diff -Nru a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c --- a/drivers/scsi/sym53c8xx_2/sym_malloc.c Tue Feb 18 01:03:47 2003 +++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c Tue Feb 18 01:03:47 2003 @@ -143,12 +143,15 @@ a = (m_addr_t) ptr; while (1) { -#ifdef SYM_MEM_FREE_UNUSED if (s == SYM_MEM_CLUSTER_SIZE) { +#ifdef SYM_MEM_FREE_UNUSED M_FREE_MEM_CLUSTER(a); +#else + ((m_link_p) a)->next = h[i].next; + h[i].next = (m_link_p) a; +#endif break; } -#endif b = a ^ s; q = &h[i]; while (q->next && q->next != (m_link_p) b) { diff -Nru a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c --- a/drivers/scsi/tmscsim.c Tue Feb 18 01:03:48 2003 +++ b/drivers/scsi/tmscsim.c Tue Feb 18 01:03:48 2003 @@ -2206,7 +2206,7 @@ psh = scsi_register( psht, sizeof(DC390_ACB) ); if( !psh ) return( -1 ); - scsi_set_pci_device(psh, pdev); + scsi_set_device(psh, &pdev->dev); pACB = (PACB) psh->hostdata; DC390_LOCKA_INIT; DC390_LOCK_ACB; diff -Nru a/fs/nfsctl.c b/fs/nfsctl.c --- a/fs/nfsctl.c Tue Feb 18 01:03:48 2003 +++ b/fs/nfsctl.c Tue Feb 18 01:03:48 2003 @@ -54,13 +54,36 @@ static struct { char *name; int wsize; int rsize; } map[] = { - [NFSCTL_SVC]={".svc", sizeof(struct nfsctl_svc)}, - [NFSCTL_ADDCLIENT]={".add", sizeof(struct nfsctl_client)}, - [NFSCTL_DELCLIENT]={".del", sizeof(struct nfsctl_client)}, - [NFSCTL_EXPORT]={".export", sizeof(struct nfsctl_export)}, - [NFSCTL_UNEXPORT]={".unexport", sizeof(struct nfsctl_export)}, - [NFSCTL_GETFD]={".getfd", sizeof(struct nfsctl_fdparm), NFS_FHSIZE}, - [NFSCTL_GETFS]={".getfs", sizeof(struct nfsctl_fsparm), sizeof(struct knfsd_fh)}, + [NFSCTL_SVC] = { + .name = ".svc", + .wsize = sizeof(struct nfsctl_svc) + }, + [NFSCTL_ADDCLIENT] = { + .name = ".add", + .wsize = sizeof(struct nfsctl_client) + }, + [NFSCTL_DELCLIENT] = { + .name = ".del", + .wsize = sizeof(struct nfsctl_client) + }, + [NFSCTL_EXPORT] = { + .name = ".export", + .wsize = sizeof(struct nfsctl_export) + }, + [NFSCTL_UNEXPORT] = { + .name = ".unexport", + .wsize = sizeof(struct nfsctl_export) + }, + [NFSCTL_GETFD] = { + .name = ".getfd", + .wsize = sizeof(struct nfsctl_fdparm), + .rsize = NFS_FHSIZE + }, + [NFSCTL_GETFS] = { + .name = ".getfs", + .wsize = sizeof(struct nfsctl_fsparm), + .rsize = sizeof(struct knfsd_fh) + }, }; long diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c --- a/fs/nfsd/export.c Tue Feb 18 01:03:47 2003 +++ b/fs/nfsd/export.c Tue Feb 18 01:03:47 2003 @@ -692,7 +692,7 @@ new.ex_anon_gid = nxp->ex_anon_gid; new.ex_fsid = nxp->ex_dev; - exp = svc_export_lookup(&new, 2); + exp = svc_export_lookup(&new, 1); if (exp == NULL) goto finish; diff -Nru a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c --- a/fs/nfsd/nfs3xdr.c Tue Feb 18 01:03:47 2003 +++ b/fs/nfsd/nfs3xdr.c Tue Feb 18 01:03:47 2003 @@ -202,7 +202,6 @@ static inline u32 * encode_saved_post_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp) { - struct timespec time; struct inode *inode = fhp->fh_dentry->d_inode; /* Attributes to follow */ @@ -228,13 +227,9 @@ else p = xdr_encode_hyper(p, (u64) inode->i_sb->s_dev); p = xdr_encode_hyper(p, (u64) inode->i_ino); - time.tv_sec = fhp->fh_post_atime; - time.tv_nsec = 0; - p = encode_time3(p, &time); - time.tv_sec = fhp->fh_post_mtime; - p = encode_time3(p, &time); - time.tv_sec = fhp->fh_post_ctime; - p = encode_time3(p, &time); + p = encode_time3(p, &fhp->fh_post_atime); + p = encode_time3(p, &fhp->fh_post_mtime); + p = encode_time3(p, &fhp->fh_post_ctime); return p; } @@ -266,14 +261,10 @@ if (dentry && dentry->d_inode && fhp->fh_post_saved) { if (fhp->fh_pre_saved) { - struct timespec time; *p++ = xdr_one; p = xdr_encode_hyper(p, (u64) fhp->fh_pre_size); - time.tv_nsec = 0; - time.tv_sec = fhp->fh_pre_mtime; - p = encode_time3(p, &time); - time.tv_sec = fhp->fh_pre_ctime; - p = encode_time3(p, &time); + p = encode_time3(p, &fhp->fh_pre_mtime); + p = encode_time3(p, &fhp->fh_pre_ctime); } else { *p++ = xdr_zero; } @@ -578,6 +569,9 @@ args->dircount = ntohl(*p++); args->count = ntohl(*p++); + if (args->count > PAGE_SIZE) + args->count = PAGE_SIZE; + svc_take_page(rqstp); args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); @@ -664,6 +658,7 @@ rqstp->rq_res.page_len = resp->len; if (resp->len & 3) { /* need to pad the tail */ + rqstp->rq_restailpage = 0; rqstp->rq_res.tail[0].iov_base = p; *p = 0; rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); @@ -688,6 +683,7 @@ rqstp->rq_res.page_len = resp->count; if (resp->count & 3) { /* need to pad the tail */ + rqstp->rq_restailpage = 0; rqstp->rq_res.tail[0].iov_base = p; *p = 0; rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3); diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c --- a/fs/nfsd/nfs4proc.c Tue Feb 18 01:03:48 2003 +++ b/fs/nfsd/nfs4proc.c Tue Feb 18 01:03:48 2003 @@ -568,9 +568,9 @@ resp->xbuf = &rqstp->rq_res; resp->p = rqstp->rq_res.head[0].iov_base + rqstp->rq_res.head[0].iov_len; - resp->tagp = resp->p + 1; /* skip over status */ - /* reserve space for: status, taglen, tag, and opcnt */ - resp->p += 3 + XDR_QUADLEN(args->taglen); + resp->tagp = resp->p; + /* reserve space for: taglen, tag, and opcnt */ + resp->p += 2 + XDR_QUADLEN(args->taglen); resp->end = rqstp->rq_res.head[0].iov_base + PAGE_SIZE; resp->taglen = args->taglen; resp->tag = args->tag; diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c --- a/fs/nfsd/nfs4xdr.c Tue Feb 18 01:03:47 2003 +++ b/fs/nfsd/nfs4xdr.c Tue Feb 18 01:03:47 2003 @@ -1735,6 +1735,7 @@ svc_take_page(resp->rqstp); resp->xbuf->tail[0].iov_base = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); + resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; resp->xbuf->tail[0].iov_len = 0; resp->p = resp->xbuf->tail[0].iov_base; resp->end = resp->p + PAGE_SIZE/4; @@ -1782,6 +1783,7 @@ svc_take_page(resp->rqstp); resp->xbuf->tail[0].iov_base = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); + resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; resp->xbuf->tail[0].iov_len = 0; resp->p = resp->xbuf->tail[0].iov_base; resp->end = resp->p + PAGE_SIZE/4; @@ -1859,6 +1861,7 @@ svc_take_page(resp->rqstp); resp->xbuf->tail[0].iov_base = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); + resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1; resp->xbuf->tail[0].iov_len = 0; resp->p = resp->xbuf->tail[0].iov_base; resp->end = resp->p + PAGE_SIZE/4; diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c --- a/fs/nfsd/nfssvc.c Tue Feb 18 01:03:47 2003 +++ b/fs/nfsd/nfssvc.c Tue Feb 18 01:03:47 2003 @@ -264,6 +264,7 @@ struct svc_procedure *proc; kxdrproc_t xdr; u32 nfserr; + u32 *nfserrp; dprintk("nfsd_dispatch: vers %d proc %d\n", rqstp->rq_vers, rqstp->rq_proc); @@ -290,6 +291,13 @@ return 1; } + /* need to grab the location to store the status, as + * nfsv4 does some encoding while processing + */ + nfserrp = rqstp->rq_res.head[0].iov_base + + rqstp->rq_res.head[0].iov_len; + rqstp->rq_res.head[0].iov_len += sizeof(u32); + /* Now call the procedure handler, and encode NFS status. */ nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); if (nfserr == nfserr_dropit) { @@ -297,16 +305,16 @@ nfsd_cache_update(rqstp, RC_NOCACHE, NULL); return 0; } - + if (rqstp->rq_proc != 0) - svc_putu32(&rqstp->rq_res.head[0], nfserr); + *nfserrp++ = nfserr; /* Encode result. * For NFSv2, additional info is never returned in case of an error. */ if (!(nfserr && rqstp->rq_vers == 2)) { xdr = proc->pc_encode; - if (xdr && !xdr(rqstp, (u32*)(rqstp->rq_res.head[0].iov_base+rqstp->rq_res.head[0].iov_len), + if (xdr && !xdr(rqstp, nfserrp, rqstp->rq_resp)) { /* Failed to encode result. Release cache entry */ dprintk("nfsd: failed to encode result!\n"); diff -Nru a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c --- a/fs/nfsd/nfsxdr.c Tue Feb 18 01:03:47 2003 +++ b/fs/nfsd/nfsxdr.c Tue Feb 18 01:03:47 2003 @@ -396,6 +396,7 @@ rqstp->rq_res.page_len = resp->len; if (resp->len & 3) { /* need to pad the tail */ + rqstp->rq_restailpage = 0; rqstp->rq_res.tail[0].iov_base = p; *p = 0; rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); @@ -415,6 +416,7 @@ rqstp->rq_res.page_len = resp->count; if (resp->count & 3) { /* need to pad the tail */ + rqstp->rq_restailpage = 0; rqstp->rq_res.tail[0].iov_base = p; *p = 0; rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3); diff -Nru a/include/linux/nfsd/nfsfh.h b/include/linux/nfsd/nfsfh.h --- a/include/linux/nfsd/nfsfh.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/nfsd/nfsfh.h Tue Feb 18 01:03:47 2003 @@ -165,8 +165,8 @@ /* Pre-op attributes saved during fh_lock */ __u64 fh_pre_size; /* size before operation */ - time_t fh_pre_mtime; /* mtime before oper */ - time_t fh_pre_ctime; /* ctime before oper */ + struct timespec fh_pre_mtime; /* mtime before oper */ + struct timespec fh_pre_ctime; /* ctime before oper */ /* Post-op attributes saved in fh_unlock */ umode_t fh_post_mode; /* i_mode */ @@ -177,9 +177,9 @@ unsigned long fh_post_blocks; /* i_blocks */ unsigned long fh_post_blksize;/* i_blksize */ __u32 fh_post_rdev[2];/* i_rdev */ - time_t fh_post_atime; /* i_atime */ - time_t fh_post_mtime; /* i_mtime */ - time_t fh_post_ctime; /* i_ctime */ + struct timespec fh_post_atime; /* i_atime */ + struct timespec fh_post_mtime; /* i_mtime */ + struct timespec fh_post_ctime; /* i_ctime */ #endif /* CONFIG_NFSD_V3 */ } svc_fh; @@ -263,8 +263,8 @@ inode = fhp->fh_dentry->d_inode; if (!fhp->fh_pre_saved) { - fhp->fh_pre_mtime = inode->i_mtime.tv_sec; - fhp->fh_pre_ctime = inode->i_ctime.tv_sec; + fhp->fh_pre_mtime = inode->i_mtime; + fhp->fh_pre_ctime = inode->i_ctime; fhp->fh_pre_size = inode->i_size; fhp->fh_pre_saved = 1; } @@ -296,9 +296,9 @@ } fhp->fh_post_rdev[0] = htonl((u32)major(inode->i_rdev)); fhp->fh_post_rdev[1] = htonl((u32)minor(inode->i_rdev)); - fhp->fh_post_atime = inode->i_atime.tv_sec; - fhp->fh_post_mtime = inode->i_mtime.tv_sec; - fhp->fh_post_ctime = inode->i_ctime.tv_sec; + fhp->fh_post_atime = inode->i_atime; + fhp->fh_post_mtime = inode->i_mtime; + fhp->fh_post_ctime = inode->i_ctime; fhp->fh_post_saved = 1; } #else diff -Nru a/include/linux/nfsd/xdr4.h b/include/linux/nfsd/xdr4.h --- a/include/linux/nfsd/xdr4.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/nfsd/xdr4.h Tue Feb 18 01:03:47 2003 @@ -331,9 +331,9 @@ BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); cinfo->atomic = 1; cinfo->before_size = fhp->fh_pre_size; - cinfo->before_ctime = fhp->fh_pre_ctime; + cinfo->before_ctime = fhp->fh_pre_ctime.tv_sec; cinfo->after_size = fhp->fh_post_size; - cinfo->after_ctime = fhp->fh_post_ctime; + cinfo->after_ctime = fhp->fh_post_ctime.tv_sec; } int nfs4svc_encode_voidres(struct svc_rqst *, u32 *, void *); diff -Nru a/include/linux/raid/md.h b/include/linux/raid/md.h --- a/include/linux/raid/md.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/raid/md.h Tue Feb 18 01:03:47 2003 @@ -73,6 +73,9 @@ extern void md_unregister_thread (mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_interrupt_thread (mdk_thread_t *thread); +extern void md_write_start(mddev_t *mddev); +extern void md_write_end(mddev_t *mddev, mdk_thread_t *thread); +extern void md_handle_safemode(mddev_t *mddev); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); extern void md_sync_acct(mdk_rdev_t *rdev, unsigned long nr_sectors); extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev); diff -Nru a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h --- a/include/linux/raid/md_k.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/raid/md_k.h Tue Feb 18 01:03:47 2003 @@ -29,6 +29,7 @@ #define LEVEL_LINEAR (-1) #define MaxSector (~(sector_t)0) +#define MD_THREAD_NAME_MAX 14 static inline int pers_to_level (int pers) { @@ -229,7 +230,10 @@ atomic_t recovery_active; /* blocks scheduled, but not written */ wait_queue_head_t recovery_wait; sector_t recovery_cp; - + int safemode; /* if set, update "clean" superblock + * when no writes pending. + */ + atomic_t writes_pending; request_queue_t queue; /* for plugging ... */ struct list_head all_mddevs; diff -Nru a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h --- a/include/linux/raid/raid1.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/raid/raid1.h Tue Feb 18 01:03:47 2003 @@ -34,6 +34,7 @@ mempool_t *r1bio_pool; mempool_t *r1buf_pool; + char thread_name[MD_THREAD_NAME_MAX]; }; typedef struct r1_private_data_s conf_t; diff -Nru a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h --- a/include/linux/raid/raid5.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/raid/raid5.h Tue Feb 18 01:03:47 2003 @@ -226,6 +226,7 @@ * waiting for 25% to be free */ spinlock_t device_lock; + char thread_name[MD_THREAD_NAME_MAX]; }; typedef struct raid5_private_data raid5_conf_t; diff -Nru a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h --- a/include/linux/sunrpc/svc.h Tue Feb 18 01:03:47 2003 +++ b/include/linux/sunrpc/svc.h Tue Feb 18 01:03:47 2003 @@ -114,6 +114,7 @@ struct xdr_buf rq_res; struct page * rq_argpages[RPCSVC_MAXPAGES]; struct page * rq_respages[RPCSVC_MAXPAGES]; + int rq_restailpage; short rq_argused; /* pages used for argument */ short rq_arghi; /* pages available in argument page list */ short rq_resused; /* pages used for result */ diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c --- a/net/sunrpc/svcsock.c Tue Feb 18 01:03:47 2003 +++ b/net/sunrpc/svcsock.c Tue Feb 18 01:03:47 2003 @@ -388,7 +388,7 @@ /* send tail */ if (xdr->tail[0].iov_len) { /* The tail *will* be in respages[0]; */ - result = sock->ops->sendpage(sock, rqstp->rq_respages[0], + result = sock->ops->sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage], ((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1), xdr->tail[0].iov_len, 0);