diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/DAC960.c | 157 | ||||
-rw-r--r-- | drivers/block/Kconfig | 12 | ||||
-rw-r--r-- | drivers/block/Makefile | 1 | ||||
-rw-r--r-- | drivers/block/aoe/aoe.h | 9 | ||||
-rw-r--r-- | drivers/block/aoe/aoeblk.c | 14 | ||||
-rw-r--r-- | drivers/block/aoe/aoechr.c | 29 | ||||
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 106 | ||||
-rw-r--r-- | drivers/block/aoe/aoedev.c | 14 | ||||
-rw-r--r-- | drivers/block/aoe/aoemain.c | 1 | ||||
-rw-r--r-- | drivers/block/aoe/aoenet.c | 11 | ||||
-rw-r--r-- | drivers/block/ataflop.c | 4 | ||||
-rw-r--r-- | drivers/block/brd.c | 2 | ||||
-rw-r--r-- | drivers/block/cciss.c | 820 | ||||
-rw-r--r-- | drivers/block/cciss.h | 2 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.c | 330 | ||||
-rw-r--r-- | drivers/block/cciss_scsi.h | 4 | ||||
-rw-r--r-- | drivers/block/cpqarray.c | 2 | ||||
-rw-r--r-- | drivers/block/floppy.c | 31 | ||||
-rw-r--r-- | drivers/block/hd.c | 815 | ||||
-rw-r--r-- | drivers/block/nbd.c | 14 | ||||
-rw-r--r-- | drivers/block/paride/pd.c | 20 | ||||
-rw-r--r-- | drivers/block/paride/pg.c | 27 | ||||
-rw-r--r-- | drivers/block/paride/pt.c | 37 | ||||
-rw-r--r-- | drivers/block/pktcdvd.c | 19 | ||||
-rw-r--r-- | drivers/block/ps3disk.c | 11 | ||||
-rw-r--r-- | drivers/block/virtio_blk.c | 24 | ||||
-rw-r--r-- | drivers/block/xen-blkfront.c | 126 |
27 files changed, 1879 insertions, 763 deletions
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index cd03473f354..a002a381df9 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -6628,15 +6628,18 @@ static void DAC960_DestroyProcEntries(DAC960_Controller_T *Controller) | |||
6628 | * DAC960_gam_ioctl is the ioctl function for performing RAID operations. | 6628 | * DAC960_gam_ioctl is the ioctl function for performing RAID operations. |
6629 | */ | 6629 | */ |
6630 | 6630 | ||
6631 | static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | 6631 | static long DAC960_gam_ioctl(struct file *file, unsigned int Request, |
6632 | unsigned int Request, unsigned long Argument) | 6632 | unsigned long Argument) |
6633 | { | 6633 | { |
6634 | int ErrorCode = 0; | 6634 | long ErrorCode = 0; |
6635 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; | 6635 | if (!capable(CAP_SYS_ADMIN)) return -EACCES; |
6636 | |||
6637 | lock_kernel(); | ||
6636 | switch (Request) | 6638 | switch (Request) |
6637 | { | 6639 | { |
6638 | case DAC960_IOCTL_GET_CONTROLLER_COUNT: | 6640 | case DAC960_IOCTL_GET_CONTROLLER_COUNT: |
6639 | return DAC960_ControllerCount; | 6641 | ErrorCode = DAC960_ControllerCount; |
6642 | break; | ||
6640 | case DAC960_IOCTL_GET_CONTROLLER_INFO: | 6643 | case DAC960_IOCTL_GET_CONTROLLER_INFO: |
6641 | { | 6644 | { |
6642 | DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = | 6645 | DAC960_ControllerInfo_T __user *UserSpaceControllerInfo = |
@@ -6644,15 +6647,20 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6644 | DAC960_ControllerInfo_T ControllerInfo; | 6647 | DAC960_ControllerInfo_T ControllerInfo; |
6645 | DAC960_Controller_T *Controller; | 6648 | DAC960_Controller_T *Controller; |
6646 | int ControllerNumber; | 6649 | int ControllerNumber; |
6647 | if (UserSpaceControllerInfo == NULL) return -EINVAL; | 6650 | if (UserSpaceControllerInfo == NULL) |
6648 | ErrorCode = get_user(ControllerNumber, | 6651 | ErrorCode = -EINVAL; |
6652 | else ErrorCode = get_user(ControllerNumber, | ||
6649 | &UserSpaceControllerInfo->ControllerNumber); | 6653 | &UserSpaceControllerInfo->ControllerNumber); |
6650 | if (ErrorCode != 0) return ErrorCode; | 6654 | if (ErrorCode != 0) |
6655 | break;; | ||
6656 | ErrorCode = -ENXIO; | ||
6651 | if (ControllerNumber < 0 || | 6657 | if (ControllerNumber < 0 || |
6652 | ControllerNumber > DAC960_ControllerCount - 1) | 6658 | ControllerNumber > DAC960_ControllerCount - 1) { |
6653 | return -ENXIO; | 6659 | break; |
6660 | } | ||
6654 | Controller = DAC960_Controllers[ControllerNumber]; | 6661 | Controller = DAC960_Controllers[ControllerNumber]; |
6655 | if (Controller == NULL) return -ENXIO; | 6662 | if (Controller == NULL) |
6663 | break;; | ||
6656 | memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); | 6664 | memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T)); |
6657 | ControllerInfo.ControllerNumber = ControllerNumber; | 6665 | ControllerInfo.ControllerNumber = ControllerNumber; |
6658 | ControllerInfo.FirmwareType = Controller->FirmwareType; | 6666 | ControllerInfo.FirmwareType = Controller->FirmwareType; |
@@ -6665,8 +6673,9 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6665 | ControllerInfo.PCI_Address = Controller->PCI_Address; | 6673 | ControllerInfo.PCI_Address = Controller->PCI_Address; |
6666 | strcpy(ControllerInfo.ModelName, Controller->ModelName); | 6674 | strcpy(ControllerInfo.ModelName, Controller->ModelName); |
6667 | strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); | 6675 | strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion); |
6668 | return (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, | 6676 | ErrorCode = (copy_to_user(UserSpaceControllerInfo, &ControllerInfo, |
6669 | sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); | 6677 | sizeof(DAC960_ControllerInfo_T)) ? -EFAULT : 0); |
6678 | break; | ||
6670 | } | 6679 | } |
6671 | case DAC960_IOCTL_V1_EXECUTE_COMMAND: | 6680 | case DAC960_IOCTL_V1_EXECUTE_COMMAND: |
6672 | { | 6681 | { |
@@ -6684,30 +6693,39 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6684 | int ControllerNumber, DataTransferLength; | 6693 | int ControllerNumber, DataTransferLength; |
6685 | unsigned char *DataTransferBuffer = NULL; | 6694 | unsigned char *DataTransferBuffer = NULL; |
6686 | dma_addr_t DataTransferBufferDMA; | 6695 | dma_addr_t DataTransferBufferDMA; |
6687 | if (UserSpaceUserCommand == NULL) return -EINVAL; | 6696 | if (UserSpaceUserCommand == NULL) { |
6697 | ErrorCode = -EINVAL; | ||
6698 | break; | ||
6699 | } | ||
6688 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, | 6700 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, |
6689 | sizeof(DAC960_V1_UserCommand_T))) { | 6701 | sizeof(DAC960_V1_UserCommand_T))) { |
6690 | ErrorCode = -EFAULT; | 6702 | ErrorCode = -EFAULT; |
6691 | goto Failure1a; | 6703 | break; |
6692 | } | 6704 | } |
6693 | ControllerNumber = UserCommand.ControllerNumber; | 6705 | ControllerNumber = UserCommand.ControllerNumber; |
6706 | ErrorCode = -ENXIO; | ||
6694 | if (ControllerNumber < 0 || | 6707 | if (ControllerNumber < 0 || |
6695 | ControllerNumber > DAC960_ControllerCount - 1) | 6708 | ControllerNumber > DAC960_ControllerCount - 1) |
6696 | return -ENXIO; | 6709 | break; |
6697 | Controller = DAC960_Controllers[ControllerNumber]; | 6710 | Controller = DAC960_Controllers[ControllerNumber]; |
6698 | if (Controller == NULL) return -ENXIO; | 6711 | if (Controller == NULL) |
6699 | if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL; | 6712 | break; |
6713 | ErrorCode = -EINVAL; | ||
6714 | if (Controller->FirmwareType != DAC960_V1_Controller) | ||
6715 | break; | ||
6700 | CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; | 6716 | CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode; |
6701 | DataTransferLength = UserCommand.DataTransferLength; | 6717 | DataTransferLength = UserCommand.DataTransferLength; |
6702 | if (CommandOpcode & 0x80) return -EINVAL; | 6718 | if (CommandOpcode & 0x80) |
6719 | break; | ||
6703 | if (CommandOpcode == DAC960_V1_DCDB) | 6720 | if (CommandOpcode == DAC960_V1_DCDB) |
6704 | { | 6721 | { |
6705 | if (copy_from_user(&DCDB, UserCommand.DCDB, | 6722 | if (copy_from_user(&DCDB, UserCommand.DCDB, |
6706 | sizeof(DAC960_V1_DCDB_T))) { | 6723 | sizeof(DAC960_V1_DCDB_T))) { |
6707 | ErrorCode = -EFAULT; | 6724 | ErrorCode = -EFAULT; |
6708 | goto Failure1a; | 6725 | break; |
6709 | } | 6726 | } |
6710 | if (DCDB.Channel >= DAC960_V1_MaxChannels) return -EINVAL; | 6727 | if (DCDB.Channel >= DAC960_V1_MaxChannels) |
6728 | break; | ||
6711 | if (!((DataTransferLength == 0 && | 6729 | if (!((DataTransferLength == 0 && |
6712 | DCDB.Direction | 6730 | DCDB.Direction |
6713 | == DAC960_V1_DCDB_NoDataTransfer) || | 6731 | == DAC960_V1_DCDB_NoDataTransfer) || |
@@ -6717,38 +6735,37 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6717 | (DataTransferLength < 0 && | 6735 | (DataTransferLength < 0 && |
6718 | DCDB.Direction | 6736 | DCDB.Direction |
6719 | == DAC960_V1_DCDB_DataTransferSystemToDevice))) | 6737 | == DAC960_V1_DCDB_DataTransferSystemToDevice))) |
6720 | return -EINVAL; | 6738 | break; |
6721 | if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) | 6739 | if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength) |
6722 | != abs(DataTransferLength)) | 6740 | != abs(DataTransferLength)) |
6723 | return -EINVAL; | 6741 | break; |
6724 | DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, | 6742 | DCDB_IOBUF = pci_alloc_consistent(Controller->PCIDevice, |
6725 | sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); | 6743 | sizeof(DAC960_V1_DCDB_T), &DCDB_IOBUFDMA); |
6726 | if (DCDB_IOBUF == NULL) | 6744 | if (DCDB_IOBUF == NULL) { |
6727 | return -ENOMEM; | 6745 | ErrorCode = -ENOMEM; |
6746 | break; | ||
6747 | } | ||
6728 | } | 6748 | } |
6749 | ErrorCode = -ENOMEM; | ||
6729 | if (DataTransferLength > 0) | 6750 | if (DataTransferLength > 0) |
6730 | { | 6751 | { |
6731 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6752 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6732 | DataTransferLength, &DataTransferBufferDMA); | 6753 | DataTransferLength, &DataTransferBufferDMA); |
6733 | if (DataTransferBuffer == NULL) { | 6754 | if (DataTransferBuffer == NULL) |
6734 | ErrorCode = -ENOMEM; | 6755 | break; |
6735 | goto Failure1; | ||
6736 | } | ||
6737 | memset(DataTransferBuffer, 0, DataTransferLength); | 6756 | memset(DataTransferBuffer, 0, DataTransferLength); |
6738 | } | 6757 | } |
6739 | else if (DataTransferLength < 0) | 6758 | else if (DataTransferLength < 0) |
6740 | { | 6759 | { |
6741 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6760 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6742 | -DataTransferLength, &DataTransferBufferDMA); | 6761 | -DataTransferLength, &DataTransferBufferDMA); |
6743 | if (DataTransferBuffer == NULL) { | 6762 | if (DataTransferBuffer == NULL) |
6744 | ErrorCode = -ENOMEM; | 6763 | break; |
6745 | goto Failure1; | ||
6746 | } | ||
6747 | if (copy_from_user(DataTransferBuffer, | 6764 | if (copy_from_user(DataTransferBuffer, |
6748 | UserCommand.DataTransferBuffer, | 6765 | UserCommand.DataTransferBuffer, |
6749 | -DataTransferLength)) { | 6766 | -DataTransferLength)) { |
6750 | ErrorCode = -EFAULT; | 6767 | ErrorCode = -EFAULT; |
6751 | goto Failure1; | 6768 | break; |
6752 | } | 6769 | } |
6753 | } | 6770 | } |
6754 | if (CommandOpcode == DAC960_V1_DCDB) | 6771 | if (CommandOpcode == DAC960_V1_DCDB) |
@@ -6825,8 +6842,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6825 | if (DCDB_IOBUF != NULL) | 6842 | if (DCDB_IOBUF != NULL) |
6826 | pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), | 6843 | pci_free_consistent(Controller->PCIDevice, sizeof(DAC960_V1_DCDB_T), |
6827 | DCDB_IOBUF, DCDB_IOBUFDMA); | 6844 | DCDB_IOBUF, DCDB_IOBUFDMA); |
6828 | Failure1a: | 6845 | break; |
6829 | return ErrorCode; | ||
6830 | } | 6846 | } |
6831 | case DAC960_IOCTL_V2_EXECUTE_COMMAND: | 6847 | case DAC960_IOCTL_V2_EXECUTE_COMMAND: |
6832 | { | 6848 | { |
@@ -6844,32 +6860,43 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6844 | dma_addr_t DataTransferBufferDMA; | 6860 | dma_addr_t DataTransferBufferDMA; |
6845 | unsigned char *RequestSenseBuffer = NULL; | 6861 | unsigned char *RequestSenseBuffer = NULL; |
6846 | dma_addr_t RequestSenseBufferDMA; | 6862 | dma_addr_t RequestSenseBufferDMA; |
6847 | if (UserSpaceUserCommand == NULL) return -EINVAL; | 6863 | |
6864 | ErrorCode = -EINVAL; | ||
6865 | if (UserSpaceUserCommand == NULL) | ||
6866 | break; | ||
6848 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, | 6867 | if (copy_from_user(&UserCommand, UserSpaceUserCommand, |
6849 | sizeof(DAC960_V2_UserCommand_T))) { | 6868 | sizeof(DAC960_V2_UserCommand_T))) { |
6850 | ErrorCode = -EFAULT; | 6869 | ErrorCode = -EFAULT; |
6851 | goto Failure2a; | 6870 | break; |
6852 | } | 6871 | } |
6872 | ErrorCode = -ENXIO; | ||
6853 | ControllerNumber = UserCommand.ControllerNumber; | 6873 | ControllerNumber = UserCommand.ControllerNumber; |
6854 | if (ControllerNumber < 0 || | 6874 | if (ControllerNumber < 0 || |
6855 | ControllerNumber > DAC960_ControllerCount - 1) | 6875 | ControllerNumber > DAC960_ControllerCount - 1) |
6856 | return -ENXIO; | 6876 | break; |
6857 | Controller = DAC960_Controllers[ControllerNumber]; | 6877 | Controller = DAC960_Controllers[ControllerNumber]; |
6858 | if (Controller == NULL) return -ENXIO; | 6878 | if (Controller == NULL) |
6859 | if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; | 6879 | break; |
6880 | if (Controller->FirmwareType != DAC960_V2_Controller){ | ||
6881 | ErrorCode = -EINVAL; | ||
6882 | break; | ||
6883 | } | ||
6860 | DataTransferLength = UserCommand.DataTransferLength; | 6884 | DataTransferLength = UserCommand.DataTransferLength; |
6885 | ErrorCode = -ENOMEM; | ||
6861 | if (DataTransferLength > 0) | 6886 | if (DataTransferLength > 0) |
6862 | { | 6887 | { |
6863 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6888 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6864 | DataTransferLength, &DataTransferBufferDMA); | 6889 | DataTransferLength, &DataTransferBufferDMA); |
6865 | if (DataTransferBuffer == NULL) return -ENOMEM; | 6890 | if (DataTransferBuffer == NULL) |
6891 | break; | ||
6866 | memset(DataTransferBuffer, 0, DataTransferLength); | 6892 | memset(DataTransferBuffer, 0, DataTransferLength); |
6867 | } | 6893 | } |
6868 | else if (DataTransferLength < 0) | 6894 | else if (DataTransferLength < 0) |
6869 | { | 6895 | { |
6870 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, | 6896 | DataTransferBuffer = pci_alloc_consistent(Controller->PCIDevice, |
6871 | -DataTransferLength, &DataTransferBufferDMA); | 6897 | -DataTransferLength, &DataTransferBufferDMA); |
6872 | if (DataTransferBuffer == NULL) return -ENOMEM; | 6898 | if (DataTransferBuffer == NULL) |
6899 | break; | ||
6873 | if (copy_from_user(DataTransferBuffer, | 6900 | if (copy_from_user(DataTransferBuffer, |
6874 | UserCommand.DataTransferBuffer, | 6901 | UserCommand.DataTransferBuffer, |
6875 | -DataTransferLength)) { | 6902 | -DataTransferLength)) { |
@@ -6979,8 +7006,7 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6979 | if (RequestSenseBuffer != NULL) | 7006 | if (RequestSenseBuffer != NULL) |
6980 | pci_free_consistent(Controller->PCIDevice, RequestSenseLength, | 7007 | pci_free_consistent(Controller->PCIDevice, RequestSenseLength, |
6981 | RequestSenseBuffer, RequestSenseBufferDMA); | 7008 | RequestSenseBuffer, RequestSenseBufferDMA); |
6982 | Failure2a: | 7009 | break; |
6983 | return ErrorCode; | ||
6984 | } | 7010 | } |
6985 | case DAC960_IOCTL_V2_GET_HEALTH_STATUS: | 7011 | case DAC960_IOCTL_V2_GET_HEALTH_STATUS: |
6986 | { | 7012 | { |
@@ -6990,21 +7016,33 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
6990 | DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; | 7016 | DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer; |
6991 | DAC960_Controller_T *Controller; | 7017 | DAC960_Controller_T *Controller; |
6992 | int ControllerNumber; | 7018 | int ControllerNumber; |
6993 | if (UserSpaceGetHealthStatus == NULL) return -EINVAL; | 7019 | if (UserSpaceGetHealthStatus == NULL) { |
7020 | ErrorCode = -EINVAL; | ||
7021 | break; | ||
7022 | } | ||
6994 | if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, | 7023 | if (copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus, |
6995 | sizeof(DAC960_V2_GetHealthStatus_T))) | 7024 | sizeof(DAC960_V2_GetHealthStatus_T))) { |
6996 | return -EFAULT; | 7025 | ErrorCode = -EFAULT; |
7026 | break; | ||
7027 | } | ||
7028 | ErrorCode = -ENXIO; | ||
6997 | ControllerNumber = GetHealthStatus.ControllerNumber; | 7029 | ControllerNumber = GetHealthStatus.ControllerNumber; |
6998 | if (ControllerNumber < 0 || | 7030 | if (ControllerNumber < 0 || |
6999 | ControllerNumber > DAC960_ControllerCount - 1) | 7031 | ControllerNumber > DAC960_ControllerCount - 1) |
7000 | return -ENXIO; | 7032 | break; |
7001 | Controller = DAC960_Controllers[ControllerNumber]; | 7033 | Controller = DAC960_Controllers[ControllerNumber]; |
7002 | if (Controller == NULL) return -ENXIO; | 7034 | if (Controller == NULL) |
7003 | if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL; | 7035 | break; |
7036 | if (Controller->FirmwareType != DAC960_V2_Controller) { | ||
7037 | ErrorCode = -EINVAL; | ||
7038 | break; | ||
7039 | } | ||
7004 | if (copy_from_user(&HealthStatusBuffer, | 7040 | if (copy_from_user(&HealthStatusBuffer, |
7005 | GetHealthStatus.HealthStatusBuffer, | 7041 | GetHealthStatus.HealthStatusBuffer, |
7006 | sizeof(DAC960_V2_HealthStatusBuffer_T))) | 7042 | sizeof(DAC960_V2_HealthStatusBuffer_T))) { |
7007 | return -EFAULT; | 7043 | ErrorCode = -EFAULT; |
7044 | break; | ||
7045 | } | ||
7008 | while (Controller->V2.HealthStatusBuffer->StatusChangeCounter | 7046 | while (Controller->V2.HealthStatusBuffer->StatusChangeCounter |
7009 | == HealthStatusBuffer.StatusChangeCounter && | 7047 | == HealthStatusBuffer.StatusChangeCounter && |
7010 | Controller->V2.HealthStatusBuffer->NextEventSequenceNumber | 7048 | Controller->V2.HealthStatusBuffer->NextEventSequenceNumber |
@@ -7012,21 +7050,28 @@ static int DAC960_gam_ioctl(struct inode *inode, struct file *file, | |||
7012 | { | 7050 | { |
7013 | interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, | 7051 | interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue, |
7014 | DAC960_MonitoringTimerInterval); | 7052 | DAC960_MonitoringTimerInterval); |
7015 | if (signal_pending(current)) return -EINTR; | 7053 | if (signal_pending(current)) { |
7054 | ErrorCode = -EINTR; | ||
7055 | break; | ||
7056 | } | ||
7016 | } | 7057 | } |
7017 | if (copy_to_user(GetHealthStatus.HealthStatusBuffer, | 7058 | if (copy_to_user(GetHealthStatus.HealthStatusBuffer, |
7018 | Controller->V2.HealthStatusBuffer, | 7059 | Controller->V2.HealthStatusBuffer, |
7019 | sizeof(DAC960_V2_HealthStatusBuffer_T))) | 7060 | sizeof(DAC960_V2_HealthStatusBuffer_T))) |
7020 | return -EFAULT; | 7061 | ErrorCode = -EFAULT; |
7021 | return 0; | 7062 | else |
7063 | ErrorCode = 0; | ||
7022 | } | 7064 | } |
7065 | default: | ||
7066 | ErrorCode = -ENOTTY; | ||
7023 | } | 7067 | } |
7024 | return -EINVAL; | 7068 | unlock_kernel(); |
7069 | return ErrorCode; | ||
7025 | } | 7070 | } |
7026 | 7071 | ||
7027 | static const struct file_operations DAC960_gam_fops = { | 7072 | static const struct file_operations DAC960_gam_fops = { |
7028 | .owner = THIS_MODULE, | 7073 | .owner = THIS_MODULE, |
7029 | .ioctl = DAC960_gam_ioctl | 7074 | .unlocked_ioctl = DAC960_gam_ioctl |
7030 | }; | 7075 | }; |
7031 | 7076 | ||
7032 | static struct miscdevice DAC960_gam_dev = { | 7077 | static struct miscdevice DAC960_gam_dev = { |
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 0d1d2133d9b..61ad8d639ba 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
@@ -433,4 +433,16 @@ config VIRTIO_BLK | |||
433 | This is the virtual block driver for virtio. It can be used with | 433 | This is the virtual block driver for virtio. It can be used with |
434 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. | 434 | lguest or QEMU based VMMs (like KVM or Xen). Say Y or M. |
435 | 435 | ||
436 | config BLK_DEV_HD | ||
437 | bool "Very old hard disk (MFM/RLL/IDE) driver" | ||
438 | depends on HAVE_IDE | ||
439 | depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN | ||
440 | help | ||
441 | This is a very old hard disk driver that lacks the enhanced | ||
442 | functionality of the newer ones. | ||
443 | |||
444 | It is required for systems with ancient MFM/RLL/ESDI drives. | ||
445 | |||
446 | If unsure, say N. | ||
447 | |||
436 | endif # BLK_DEV | 448 | endif # BLK_DEV |
diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 5e584306be9..204332b2957 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile | |||
@@ -29,5 +29,6 @@ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o | |||
29 | obj-$(CONFIG_VIODASD) += viodasd.o | 29 | obj-$(CONFIG_VIODASD) += viodasd.o |
30 | obj-$(CONFIG_BLK_DEV_SX8) += sx8.o | 30 | obj-$(CONFIG_BLK_DEV_SX8) += sx8.o |
31 | obj-$(CONFIG_BLK_DEV_UB) += ub.o | 31 | obj-$(CONFIG_BLK_DEV_UB) += ub.o |
32 | obj-$(CONFIG_BLK_DEV_HD) += hd.o | ||
32 | 33 | ||
33 | obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o | 34 | obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o |
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 5b4c6e649c1..93f3690396a 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h | |||
@@ -159,11 +159,8 @@ struct aoedev { | |||
159 | sector_t ssize; | 159 | sector_t ssize; |
160 | struct timer_list timer; | 160 | struct timer_list timer; |
161 | spinlock_t lock; | 161 | spinlock_t lock; |
162 | struct sk_buff *sendq_hd; /* packets needing to be sent, list head */ | 162 | struct sk_buff_head sendq; |
163 | struct sk_buff *sendq_tl; | 163 | struct sk_buff_head skbpool; |
164 | struct sk_buff *skbpool_hd; | ||
165 | struct sk_buff *skbpool_tl; | ||
166 | int nskbpool; | ||
167 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ | 164 | mempool_t *bufpool; /* for deadlock-free Buf allocation */ |
168 | struct list_head bufq; /* queue of bios to work on */ | 165 | struct list_head bufq; /* queue of bios to work on */ |
169 | struct buf *inprocess; /* the one we're currently working on */ | 166 | struct buf *inprocess; /* the one we're currently working on */ |
@@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size); | |||
199 | 196 | ||
200 | int aoenet_init(void); | 197 | int aoenet_init(void); |
201 | void aoenet_exit(void); | 198 | void aoenet_exit(void); |
202 | void aoenet_xmit(struct sk_buff *); | 199 | void aoenet_xmit(struct sk_buff_head *); |
203 | int is_aoe_netif(struct net_device *ifp); | 200 | int is_aoe_netif(struct net_device *ifp); |
204 | int set_aoe_iflist(const char __user *str, size_t size); | 201 | int set_aoe_iflist(const char __user *str, size_t size); |
205 | 202 | ||
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 0c39782b266..b82654e883a 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -109,12 +109,12 @@ static const struct attribute_group attr_group = { | |||
109 | static int | 109 | static int |
110 | aoedisk_add_sysfs(struct aoedev *d) | 110 | aoedisk_add_sysfs(struct aoedev *d) |
111 | { | 111 | { |
112 | return sysfs_create_group(&d->gd->dev.kobj, &attr_group); | 112 | return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group); |
113 | } | 113 | } |
114 | void | 114 | void |
115 | aoedisk_rm_sysfs(struct aoedev *d) | 115 | aoedisk_rm_sysfs(struct aoedev *d) |
116 | { | 116 | { |
117 | sysfs_remove_group(&d->gd->dev.kobj, &attr_group); | 117 | sysfs_remove_group(&disk_to_dev(d->gd)->kobj, &attr_group); |
118 | } | 118 | } |
119 | 119 | ||
120 | static int | 120 | static int |
@@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp) | |||
158 | static int | 158 | static int |
159 | aoeblk_make_request(struct request_queue *q, struct bio *bio) | 159 | aoeblk_make_request(struct request_queue *q, struct bio *bio) |
160 | { | 160 | { |
161 | struct sk_buff_head queue; | ||
161 | struct aoedev *d; | 162 | struct aoedev *d; |
162 | struct buf *buf; | 163 | struct buf *buf; |
163 | struct sk_buff *sl; | ||
164 | ulong flags; | 164 | ulong flags; |
165 | 165 | ||
166 | blk_queue_bounce(q, &bio); | 166 | blk_queue_bounce(q, &bio); |
@@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) | |||
213 | list_add_tail(&buf->bufs, &d->bufq); | 213 | list_add_tail(&buf->bufs, &d->bufq); |
214 | 214 | ||
215 | aoecmd_work(d); | 215 | aoecmd_work(d); |
216 | sl = d->sendq_hd; | 216 | __skb_queue_head_init(&queue); |
217 | d->sendq_hd = d->sendq_tl = NULL; | 217 | skb_queue_splice_init(&d->sendq, &queue); |
218 | 218 | ||
219 | spin_unlock_irqrestore(&d->lock, flags); | 219 | spin_unlock_irqrestore(&d->lock, flags); |
220 | aoenet_xmit(sl); | 220 | aoenet_xmit(&queue); |
221 | 221 | ||
222 | return 0; | 222 | return 0; |
223 | } | 223 | } |
@@ -276,7 +276,7 @@ aoeblk_gdalloc(void *vp) | |||
276 | gd->first_minor = d->sysminor * AOE_PARTITIONS; | 276 | gd->first_minor = d->sysminor * AOE_PARTITIONS; |
277 | gd->fops = &aoe_bdops; | 277 | gd->fops = &aoe_bdops; |
278 | gd->private_data = d; | 278 | gd->private_data = d; |
279 | gd->capacity = d->ssize; | 279 | set_capacity(gd, d->ssize); |
280 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", | 280 | snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", |
281 | d->aoemajor, d->aoeminor); | 281 | d->aoemajor, d->aoeminor); |
282 | 282 | ||
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index e8e60e7a2e7..1f56d2c5b7f 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c | |||
@@ -6,7 +6,10 @@ | |||
6 | 6 | ||
7 | #include <linux/hdreg.h> | 7 | #include <linux/hdreg.h> |
8 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
9 | #include <linux/completion.h> | ||
9 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/smp_lock.h> | ||
12 | #include <linux/skbuff.h> | ||
10 | #include "aoe.h" | 13 | #include "aoe.h" |
11 | 14 | ||
12 | enum { | 15 | enum { |
@@ -35,7 +38,7 @@ struct ErrMsg { | |||
35 | 38 | ||
36 | static struct ErrMsg emsgs[NMSG]; | 39 | static struct ErrMsg emsgs[NMSG]; |
37 | static int emsgs_head_idx, emsgs_tail_idx; | 40 | static int emsgs_head_idx, emsgs_tail_idx; |
38 | static struct semaphore emsgs_sema; | 41 | static struct completion emsgs_comp; |
39 | static spinlock_t emsgs_lock; | 42 | static spinlock_t emsgs_lock; |
40 | static int nblocked_emsgs_readers; | 43 | static int nblocked_emsgs_readers; |
41 | static struct class *aoe_class; | 44 | static struct class *aoe_class; |
@@ -101,7 +104,12 @@ loop: | |||
101 | spin_lock_irqsave(&d->lock, flags); | 104 | spin_lock_irqsave(&d->lock, flags); |
102 | goto loop; | 105 | goto loop; |
103 | } | 106 | } |
104 | aoenet_xmit(skb); | 107 | if (skb) { |
108 | struct sk_buff_head queue; | ||
109 | __skb_queue_head_init(&queue); | ||
110 | __skb_queue_tail(&queue, skb); | ||
111 | aoenet_xmit(&queue); | ||
112 | } | ||
105 | aoecmd_cfg(major, minor); | 113 | aoecmd_cfg(major, minor); |
106 | return 0; | 114 | return 0; |
107 | } | 115 | } |
@@ -140,7 +148,7 @@ bail: spin_unlock_irqrestore(&emsgs_lock, flags); | |||
140 | spin_unlock_irqrestore(&emsgs_lock, flags); | 148 | spin_unlock_irqrestore(&emsgs_lock, flags); |
141 | 149 | ||
142 | if (nblocked_emsgs_readers) | 150 | if (nblocked_emsgs_readers) |
143 | up(&emsgs_sema); | 151 | complete(&emsgs_comp); |
144 | } | 152 | } |
145 | 153 | ||
146 | static ssize_t | 154 | static ssize_t |
@@ -174,12 +182,16 @@ aoechr_open(struct inode *inode, struct file *filp) | |||
174 | { | 182 | { |
175 | int n, i; | 183 | int n, i; |
176 | 184 | ||
185 | lock_kernel(); | ||
177 | n = iminor(inode); | 186 | n = iminor(inode); |
178 | filp->private_data = (void *) (unsigned long) n; | 187 | filp->private_data = (void *) (unsigned long) n; |
179 | 188 | ||
180 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) | 189 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) |
181 | if (chardevs[i].minor == n) | 190 | if (chardevs[i].minor == n) { |
191 | unlock_kernel(); | ||
182 | return 0; | 192 | return 0; |
193 | } | ||
194 | unlock_kernel(); | ||
183 | return -EINVAL; | 195 | return -EINVAL; |
184 | } | 196 | } |
185 | 197 | ||
@@ -216,7 +228,7 @@ aoechr_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) | |||
216 | 228 | ||
217 | spin_unlock_irqrestore(&emsgs_lock, flags); | 229 | spin_unlock_irqrestore(&emsgs_lock, flags); |
218 | 230 | ||
219 | n = down_interruptible(&emsgs_sema); | 231 | n = wait_for_completion_interruptible(&emsgs_comp); |
220 | 232 | ||
221 | spin_lock_irqsave(&emsgs_lock, flags); | 233 | spin_lock_irqsave(&emsgs_lock, flags); |
222 | 234 | ||
@@ -264,7 +276,7 @@ aoechr_init(void) | |||
264 | printk(KERN_ERR "aoe: can't register char device\n"); | 276 | printk(KERN_ERR "aoe: can't register char device\n"); |
265 | return n; | 277 | return n; |
266 | } | 278 | } |
267 | sema_init(&emsgs_sema, 0); | 279 | init_completion(&emsgs_comp); |
268 | spin_lock_init(&emsgs_lock); | 280 | spin_lock_init(&emsgs_lock); |
269 | aoe_class = class_create(THIS_MODULE, "aoe"); | 281 | aoe_class = class_create(THIS_MODULE, "aoe"); |
270 | if (IS_ERR(aoe_class)) { | 282 | if (IS_ERR(aoe_class)) { |
@@ -272,8 +284,9 @@ aoechr_init(void) | |||
272 | return PTR_ERR(aoe_class); | 284 | return PTR_ERR(aoe_class); |
273 | } | 285 | } |
274 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) | 286 | for (i = 0; i < ARRAY_SIZE(chardevs); ++i) |
275 | device_create(aoe_class, NULL, | 287 | device_create_drvdata(aoe_class, NULL, |
276 | MKDEV(AOE_MAJOR, chardevs[i].minor), chardevs[i].name); | 288 | MKDEV(AOE_MAJOR, chardevs[i].minor), |
289 | NULL, chardevs[i].name); | ||
277 | 290 | ||
278 | return 0; | 291 | return 0; |
279 | } | 292 | } |
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 41f818be2f7..71ff78c9e4d 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t) | |||
114 | static void | 114 | static void |
115 | skb_pool_put(struct aoedev *d, struct sk_buff *skb) | 115 | skb_pool_put(struct aoedev *d, struct sk_buff *skb) |
116 | { | 116 | { |
117 | if (!d->skbpool_hd) | 117 | __skb_queue_tail(&d->skbpool, skb); |
118 | d->skbpool_hd = skb; | ||
119 | else | ||
120 | d->skbpool_tl->next = skb; | ||
121 | d->skbpool_tl = skb; | ||
122 | } | 118 | } |
123 | 119 | ||
124 | static struct sk_buff * | 120 | static struct sk_buff * |
125 | skb_pool_get(struct aoedev *d) | 121 | skb_pool_get(struct aoedev *d) |
126 | { | 122 | { |
127 | struct sk_buff *skb; | 123 | struct sk_buff *skb = skb_peek(&d->skbpool); |
128 | 124 | ||
129 | skb = d->skbpool_hd; | ||
130 | if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) { | 125 | if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) { |
131 | d->skbpool_hd = skb->next; | 126 | __skb_unlink(skb, &d->skbpool); |
132 | skb->next = NULL; | ||
133 | return skb; | 127 | return skb; |
134 | } | 128 | } |
135 | if (d->nskbpool < NSKBPOOLMAX | 129 | if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX && |
136 | && (skb = new_skb(ETH_ZLEN))) { | 130 | (skb = new_skb(ETH_ZLEN))) |
137 | d->nskbpool++; | ||
138 | return skb; | 131 | return skb; |
139 | } | 132 | |
140 | return NULL; | 133 | return NULL; |
141 | } | 134 | } |
142 | 135 | ||
@@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d) | |||
293 | 286 | ||
294 | skb->dev = t->ifp->nd; | 287 | skb->dev = t->ifp->nd; |
295 | skb = skb_clone(skb, GFP_ATOMIC); | 288 | skb = skb_clone(skb, GFP_ATOMIC); |
296 | if (skb) { | 289 | if (skb) |
297 | if (d->sendq_hd) | 290 | __skb_queue_tail(&d->sendq, skb); |
298 | d->sendq_tl->next = skb; | ||
299 | else | ||
300 | d->sendq_hd = skb; | ||
301 | d->sendq_tl = skb; | ||
302 | } | ||
303 | return 1; | 291 | return 1; |
304 | } | 292 | } |
305 | 293 | ||
306 | /* some callers cannot sleep, and they can call this function, | 294 | /* some callers cannot sleep, and they can call this function, |
307 | * transmitting the packets later, when interrupts are on | 295 | * transmitting the packets later, when interrupts are on |
308 | */ | 296 | */ |
309 | static struct sk_buff * | 297 | static void |
310 | aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | 298 | aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue) |
311 | { | 299 | { |
312 | struct aoe_hdr *h; | 300 | struct aoe_hdr *h; |
313 | struct aoe_cfghdr *ch; | 301 | struct aoe_cfghdr *ch; |
314 | struct sk_buff *skb, *sl, *sl_tail; | 302 | struct sk_buff *skb; |
315 | struct net_device *ifp; | 303 | struct net_device *ifp; |
316 | 304 | ||
317 | sl = sl_tail = NULL; | ||
318 | |||
319 | read_lock(&dev_base_lock); | 305 | read_lock(&dev_base_lock); |
320 | for_each_netdev(&init_net, ifp) { | 306 | for_each_netdev(&init_net, ifp) { |
321 | dev_hold(ifp); | 307 | dev_hold(ifp); |
@@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | |||
329 | } | 315 | } |
330 | skb_put(skb, sizeof *h + sizeof *ch); | 316 | skb_put(skb, sizeof *h + sizeof *ch); |
331 | skb->dev = ifp; | 317 | skb->dev = ifp; |
332 | if (sl_tail == NULL) | 318 | __skb_queue_tail(queue, skb); |
333 | sl_tail = skb; | ||
334 | h = (struct aoe_hdr *) skb_mac_header(skb); | 319 | h = (struct aoe_hdr *) skb_mac_header(skb); |
335 | memset(h, 0, sizeof *h + sizeof *ch); | 320 | memset(h, 0, sizeof *h + sizeof *ch); |
336 | 321 | ||
@@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) | |||
342 | h->minor = aoeminor; | 327 | h->minor = aoeminor; |
343 | h->cmd = AOECMD_CFG; | 328 | h->cmd = AOECMD_CFG; |
344 | 329 | ||
345 | skb->next = sl; | ||
346 | sl = skb; | ||
347 | cont: | 330 | cont: |
348 | dev_put(ifp); | 331 | dev_put(ifp); |
349 | } | 332 | } |
350 | read_unlock(&dev_base_lock); | 333 | read_unlock(&dev_base_lock); |
351 | |||
352 | if (tail != NULL) | ||
353 | *tail = sl_tail; | ||
354 | return sl; | ||
355 | } | 334 | } |
356 | 335 | ||
357 | static void | 336 | static void |
@@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f) | |||
406 | skb = skb_clone(skb, GFP_ATOMIC); | 385 | skb = skb_clone(skb, GFP_ATOMIC); |
407 | if (skb == NULL) | 386 | if (skb == NULL) |
408 | return; | 387 | return; |
409 | if (d->sendq_hd) | 388 | __skb_queue_tail(&d->sendq, skb); |
410 | d->sendq_tl->next = skb; | ||
411 | else | ||
412 | d->sendq_hd = skb; | ||
413 | d->sendq_tl = skb; | ||
414 | } | 389 | } |
415 | 390 | ||
416 | static int | 391 | static int |
@@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) { | |||
508 | static void | 483 | static void |
509 | rexmit_timer(ulong vp) | 484 | rexmit_timer(ulong vp) |
510 | { | 485 | { |
486 | struct sk_buff_head queue; | ||
511 | struct aoedev *d; | 487 | struct aoedev *d; |
512 | struct aoetgt *t, **tt, **te; | 488 | struct aoetgt *t, **tt, **te; |
513 | struct aoeif *ifp; | 489 | struct aoeif *ifp; |
514 | struct frame *f, *e; | 490 | struct frame *f, *e; |
515 | struct sk_buff *sl; | ||
516 | register long timeout; | 491 | register long timeout; |
517 | ulong flags, n; | 492 | ulong flags, n; |
518 | 493 | ||
519 | d = (struct aoedev *) vp; | 494 | d = (struct aoedev *) vp; |
520 | sl = NULL; | ||
521 | 495 | ||
522 | /* timeout is always ~150% of the moving average */ | 496 | /* timeout is always ~150% of the moving average */ |
523 | timeout = d->rttavg; | 497 | timeout = d->rttavg; |
@@ -589,7 +563,7 @@ rexmit_timer(ulong vp) | |||
589 | } | 563 | } |
590 | } | 564 | } |
591 | 565 | ||
592 | if (d->sendq_hd) { | 566 | if (!skb_queue_empty(&d->sendq)) { |
593 | n = d->rttavg <<= 1; | 567 | n = d->rttavg <<= 1; |
594 | if (n > MAXTIMER) | 568 | if (n > MAXTIMER) |
595 | d->rttavg = MAXTIMER; | 569 | d->rttavg = MAXTIMER; |
@@ -600,15 +574,15 @@ rexmit_timer(ulong vp) | |||
600 | aoecmd_work(d); | 574 | aoecmd_work(d); |
601 | } | 575 | } |
602 | 576 | ||
603 | sl = d->sendq_hd; | 577 | __skb_queue_head_init(&queue); |
604 | d->sendq_hd = d->sendq_tl = NULL; | 578 | skb_queue_splice_init(&d->sendq, &queue); |
605 | 579 | ||
606 | d->timer.expires = jiffies + TIMERTICK; | 580 | d->timer.expires = jiffies + TIMERTICK; |
607 | add_timer(&d->timer); | 581 | add_timer(&d->timer); |
608 | 582 | ||
609 | spin_unlock_irqrestore(&d->lock, flags); | 583 | spin_unlock_irqrestore(&d->lock, flags); |
610 | 584 | ||
611 | aoenet_xmit(sl); | 585 | aoenet_xmit(&queue); |
612 | } | 586 | } |
613 | 587 | ||
614 | /* enters with d->lock held */ | 588 | /* enters with d->lock held */ |
@@ -645,7 +619,7 @@ aoecmd_sleepwork(struct work_struct *work) | |||
645 | unsigned long flags; | 619 | unsigned long flags; |
646 | u64 ssize; | 620 | u64 ssize; |
647 | 621 | ||
648 | ssize = d->gd->capacity; | 622 | ssize = get_capacity(d->gd); |
649 | bd = bdget_disk(d->gd, 0); | 623 | bd = bdget_disk(d->gd, 0); |
650 | 624 | ||
651 | if (bd) { | 625 | if (bd) { |
@@ -707,7 +681,7 @@ ataid_complete(struct aoedev *d, struct aoetgt *t, unsigned char *id) | |||
707 | if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE)) | 681 | if (d->flags & (DEVFL_GDALLOC|DEVFL_NEWSIZE)) |
708 | return; | 682 | return; |
709 | if (d->gd != NULL) { | 683 | if (d->gd != NULL) { |
710 | d->gd->capacity = ssize; | 684 | set_capacity(d->gd, ssize); |
711 | d->flags |= DEVFL_NEWSIZE; | 685 | d->flags |= DEVFL_NEWSIZE; |
712 | } else | 686 | } else |
713 | d->flags |= DEVFL_GDALLOC; | 687 | d->flags |= DEVFL_GDALLOC; |
@@ -756,23 +730,28 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector | |||
756 | unsigned long n_sect = bio->bi_size >> 9; | 730 | unsigned long n_sect = bio->bi_size >> 9; |
757 | const int rw = bio_data_dir(bio); | 731 | const int rw = bio_data_dir(bio); |
758 | struct hd_struct *part; | 732 | struct hd_struct *part; |
733 | int cpu; | ||
734 | |||
735 | cpu = part_stat_lock(); | ||
736 | part = disk_map_sector_rcu(disk, sector); | ||
737 | |||
738 | part_stat_inc(cpu, part, ios[rw]); | ||
739 | part_stat_add(cpu, part, ticks[rw], duration); | ||
740 | part_stat_add(cpu, part, sectors[rw], n_sect); | ||
741 | part_stat_add(cpu, part, io_ticks, duration); | ||
759 | 742 | ||
760 | part = get_part(disk, sector); | 743 | part_stat_unlock(); |
761 | all_stat_inc(disk, part, ios[rw], sector); | ||
762 | all_stat_add(disk, part, ticks[rw], duration, sector); | ||
763 | all_stat_add(disk, part, sectors[rw], n_sect, sector); | ||
764 | all_stat_add(disk, part, io_ticks, duration, sector); | ||
765 | } | 744 | } |
766 | 745 | ||
767 | void | 746 | void |
768 | aoecmd_ata_rsp(struct sk_buff *skb) | 747 | aoecmd_ata_rsp(struct sk_buff *skb) |
769 | { | 748 | { |
749 | struct sk_buff_head queue; | ||
770 | struct aoedev *d; | 750 | struct aoedev *d; |
771 | struct aoe_hdr *hin, *hout; | 751 | struct aoe_hdr *hin, *hout; |
772 | struct aoe_atahdr *ahin, *ahout; | 752 | struct aoe_atahdr *ahin, *ahout; |
773 | struct frame *f; | 753 | struct frame *f; |
774 | struct buf *buf; | 754 | struct buf *buf; |
775 | struct sk_buff *sl; | ||
776 | struct aoetgt *t; | 755 | struct aoetgt *t; |
777 | struct aoeif *ifp; | 756 | struct aoeif *ifp; |
778 | register long n; | 757 | register long n; |
@@ -893,21 +872,21 @@ aoecmd_ata_rsp(struct sk_buff *skb) | |||
893 | 872 | ||
894 | aoecmd_work(d); | 873 | aoecmd_work(d); |
895 | xmit: | 874 | xmit: |
896 | sl = d->sendq_hd; | 875 | __skb_queue_head_init(&queue); |
897 | d->sendq_hd = d->sendq_tl = NULL; | 876 | skb_queue_splice_init(&d->sendq, &queue); |
898 | 877 | ||
899 | spin_unlock_irqrestore(&d->lock, flags); | 878 | spin_unlock_irqrestore(&d->lock, flags); |
900 | aoenet_xmit(sl); | 879 | aoenet_xmit(&queue); |
901 | } | 880 | } |
902 | 881 | ||
903 | void | 882 | void |
904 | aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) | 883 | aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) |
905 | { | 884 | { |
906 | struct sk_buff *sl; | 885 | struct sk_buff_head queue; |
907 | 886 | ||
908 | sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL); | 887 | __skb_queue_head_init(&queue); |
909 | 888 | aoecmd_cfg_pkts(aoemajor, aoeminor, &queue); | |
910 | aoenet_xmit(sl); | 889 | aoenet_xmit(&queue); |
911 | } | 890 | } |
912 | 891 | ||
913 | struct sk_buff * | 892 | struct sk_buff * |
@@ -1003,7 +982,7 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
1003 | * Enough people have their dip switches set backwards to | 982 | * Enough people have their dip switches set backwards to |
1004 | * warrant a loud message for this special case. | 983 | * warrant a loud message for this special case. |
1005 | */ | 984 | */ |
1006 | aoemajor = be16_to_cpu(get_unaligned(&h->major)); | 985 | aoemajor = get_unaligned_be16(&h->major); |
1007 | if (aoemajor == 0xfff) { | 986 | if (aoemajor == 0xfff) { |
1008 | printk(KERN_ERR "aoe: Warning: shelf address is all ones. " | 987 | printk(KERN_ERR "aoe: Warning: shelf address is all ones. " |
1009 | "Check shelf dip switches.\n"); | 988 | "Check shelf dip switches.\n"); |
@@ -1076,7 +1055,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb) | |||
1076 | 1055 | ||
1077 | spin_unlock_irqrestore(&d->lock, flags); | 1056 | spin_unlock_irqrestore(&d->lock, flags); |
1078 | 1057 | ||
1079 | aoenet_xmit(sl); | 1058 | if (sl) { |
1059 | struct sk_buff_head queue; | ||
1060 | __skb_queue_head_init(&queue); | ||
1061 | __skb_queue_tail(&queue, sl); | ||
1062 | aoenet_xmit(&queue); | ||
1063 | } | ||
1080 | } | 1064 | } |
1081 | 1065 | ||
1082 | void | 1066 | void |
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index a1d813ab0d6..cc250577d40 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -91,7 +91,7 @@ aoedev_downdev(struct aoedev *d) | |||
91 | } | 91 | } |
92 | 92 | ||
93 | if (d->gd) | 93 | if (d->gd) |
94 | d->gd->capacity = 0; | 94 | set_capacity(d->gd, 0); |
95 | 95 | ||
96 | d->flags &= ~DEVFL_UP; | 96 | d->flags &= ~DEVFL_UP; |
97 | } | 97 | } |
@@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb) | |||
188 | static void | 188 | static void |
189 | skbpoolfree(struct aoedev *d) | 189 | skbpoolfree(struct aoedev *d) |
190 | { | 190 | { |
191 | struct sk_buff *skb; | 191 | struct sk_buff *skb, *tmp; |
192 | 192 | ||
193 | while ((skb = d->skbpool_hd)) { | 193 | skb_queue_walk_safe(&d->skbpool, skb, tmp) |
194 | d->skbpool_hd = skb->next; | ||
195 | skb->next = NULL; | ||
196 | skbfree(skb); | 194 | skbfree(skb); |
197 | } | 195 | |
198 | d->skbpool_tl = NULL; | 196 | __skb_queue_head_init(&d->skbpool); |
199 | } | 197 | } |
200 | 198 | ||
201 | /* find it or malloc it */ | 199 | /* find it or malloc it */ |
@@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor) | |||
217 | goto out; | 215 | goto out; |
218 | INIT_WORK(&d->work, aoecmd_sleepwork); | 216 | INIT_WORK(&d->work, aoecmd_sleepwork); |
219 | spin_lock_init(&d->lock); | 217 | spin_lock_init(&d->lock); |
218 | skb_queue_head_init(&d->sendq); | ||
219 | skb_queue_head_init(&d->skbpool); | ||
220 | init_timer(&d->timer); | 220 | init_timer(&d->timer); |
221 | d->timer.data = (ulong) d; | 221 | d->timer.data = (ulong) d; |
222 | d->timer.function = dummy_timer; | 222 | d->timer.function = dummy_timer; |
diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c index 7b15a5e9cec..7f83ad90e76 100644 --- a/drivers/block/aoe/aoemain.c +++ b/drivers/block/aoe/aoemain.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/hdreg.h> | 7 | #include <linux/hdreg.h> |
8 | #include <linux/blkdev.h> | 8 | #include <linux/blkdev.h> |
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/skbuff.h> | ||
10 | #include "aoe.h" | 11 | #include "aoe.h" |
11 | 12 | ||
12 | MODULE_LICENSE("GPL"); | 13 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index d625169c8e4..9157d64270c 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c | |||
@@ -30,7 +30,7 @@ enum { | |||
30 | 30 | ||
31 | static char aoe_iflist[IFLISTSZ]; | 31 | static char aoe_iflist[IFLISTSZ]; |
32 | module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600); | 32 | module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600); |
33 | MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"\n"); | 33 | MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\""); |
34 | 34 | ||
35 | #ifndef MODULE | 35 | #ifndef MODULE |
36 | static int __init aoe_iflist_setup(char *str) | 36 | static int __init aoe_iflist_setup(char *str) |
@@ -95,13 +95,12 @@ mac_addr(char addr[6]) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | void | 97 | void |
98 | aoenet_xmit(struct sk_buff *sl) | 98 | aoenet_xmit(struct sk_buff_head *queue) |
99 | { | 99 | { |
100 | struct sk_buff *skb; | 100 | struct sk_buff *skb, *tmp; |
101 | 101 | ||
102 | while ((skb = sl)) { | 102 | skb_queue_walk_safe(queue, skb, tmp) { |
103 | sl = sl->next; | 103 | __skb_unlink(skb, queue); |
104 | skb->next = skb->prev = NULL; | ||
105 | dev_queue_xmit(skb); | 104 | dev_queue_xmit(skb); |
106 | } | 105 | } |
107 | } | 106 | } |
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 424995073c6..49f274197b1 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c | |||
@@ -1880,11 +1880,11 @@ static int __init atari_floppy_init (void) | |||
1880 | 1880 | ||
1881 | if (!MACH_IS_ATARI) | 1881 | if (!MACH_IS_ATARI) |
1882 | /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ | 1882 | /* Amiga, Mac, ... don't have Atari-compatible floppy :-) */ |
1883 | return -ENXIO; | 1883 | return -ENODEV; |
1884 | 1884 | ||
1885 | if (MACH_IS_HADES) | 1885 | if (MACH_IS_HADES) |
1886 | /* Hades doesn't have Atari-compatible floppy */ | 1886 | /* Hades doesn't have Atari-compatible floppy */ |
1887 | return -ENXIO; | 1887 | return -ENODEV; |
1888 | 1888 | ||
1889 | if (register_blkdev(FLOPPY_MAJOR,"fd")) | 1889 | if (register_blkdev(FLOPPY_MAJOR,"fd")) |
1890 | return -EBUSY; | 1890 | return -EBUSY; |
diff --git a/drivers/block/brd.c b/drivers/block/brd.c index 24b97b0bef9..d070d492e38 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c | |||
@@ -571,8 +571,8 @@ out_free: | |||
571 | list_del(&brd->brd_list); | 571 | list_del(&brd->brd_list); |
572 | brd_free(brd); | 572 | brd_free(brd); |
573 | } | 573 | } |
574 | unregister_blkdev(RAMDISK_MAJOR, "ramdisk"); | ||
574 | 575 | ||
575 | unregister_blkdev(RAMDISK_MAJOR, "brd"); | ||
576 | return -ENOMEM; | 576 | return -ENOMEM; |
577 | } | 577 | } |
578 | 578 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 5f1e1cc6165..1e1f9153000 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -106,35 +106,34 @@ MODULE_DEVICE_TABLE(pci, cciss_pci_device_id); | |||
106 | /* board_id = Subsystem Device ID & Vendor ID | 106 | /* board_id = Subsystem Device ID & Vendor ID |
107 | * product = Marketing Name for the board | 107 | * product = Marketing Name for the board |
108 | * access = Address of the struct of function pointers | 108 | * access = Address of the struct of function pointers |
109 | * nr_cmds = Number of commands supported by controller | ||
110 | */ | 109 | */ |
111 | static struct board_type products[] = { | 110 | static struct board_type products[] = { |
112 | {0x40700E11, "Smart Array 5300", &SA5_access, 512}, | 111 | {0x40700E11, "Smart Array 5300", &SA5_access}, |
113 | {0x40800E11, "Smart Array 5i", &SA5B_access, 512}, | 112 | {0x40800E11, "Smart Array 5i", &SA5B_access}, |
114 | {0x40820E11, "Smart Array 532", &SA5B_access, 512}, | 113 | {0x40820E11, "Smart Array 532", &SA5B_access}, |
115 | {0x40830E11, "Smart Array 5312", &SA5B_access, 512}, | 114 | {0x40830E11, "Smart Array 5312", &SA5B_access}, |
116 | {0x409A0E11, "Smart Array 641", &SA5_access, 512}, | 115 | {0x409A0E11, "Smart Array 641", &SA5_access}, |
117 | {0x409B0E11, "Smart Array 642", &SA5_access, 512}, | 116 | {0x409B0E11, "Smart Array 642", &SA5_access}, |
118 | {0x409C0E11, "Smart Array 6400", &SA5_access, 512}, | 117 | {0x409C0E11, "Smart Array 6400", &SA5_access}, |
119 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access, 512}, | 118 | {0x409D0E11, "Smart Array 6400 EM", &SA5_access}, |
120 | {0x40910E11, "Smart Array 6i", &SA5_access, 512}, | 119 | {0x40910E11, "Smart Array 6i", &SA5_access}, |
121 | {0x3225103C, "Smart Array P600", &SA5_access, 512}, | 120 | {0x3225103C, "Smart Array P600", &SA5_access}, |
122 | {0x3223103C, "Smart Array P800", &SA5_access, 512}, | 121 | {0x3223103C, "Smart Array P800", &SA5_access}, |
123 | {0x3234103C, "Smart Array P400", &SA5_access, 512}, | 122 | {0x3234103C, "Smart Array P400", &SA5_access}, |
124 | {0x3235103C, "Smart Array P400i", &SA5_access, 512}, | 123 | {0x3235103C, "Smart Array P400i", &SA5_access}, |
125 | {0x3211103C, "Smart Array E200i", &SA5_access, 120}, | 124 | {0x3211103C, "Smart Array E200i", &SA5_access}, |
126 | {0x3212103C, "Smart Array E200", &SA5_access, 120}, | 125 | {0x3212103C, "Smart Array E200", &SA5_access}, |
127 | {0x3213103C, "Smart Array E200i", &SA5_access, 120}, | 126 | {0x3213103C, "Smart Array E200i", &SA5_access}, |
128 | {0x3214103C, "Smart Array E200i", &SA5_access, 120}, | 127 | {0x3214103C, "Smart Array E200i", &SA5_access}, |
129 | {0x3215103C, "Smart Array E200i", &SA5_access, 120}, | 128 | {0x3215103C, "Smart Array E200i", &SA5_access}, |
130 | {0x3237103C, "Smart Array E500", &SA5_access, 512}, | 129 | {0x3237103C, "Smart Array E500", &SA5_access}, |
131 | {0x323D103C, "Smart Array P700m", &SA5_access, 512}, | 130 | {0x323D103C, "Smart Array P700m", &SA5_access}, |
132 | {0x3241103C, "Smart Array P212", &SA5_access, 384}, | 131 | {0x3241103C, "Smart Array P212", &SA5_access}, |
133 | {0x3243103C, "Smart Array P410", &SA5_access, 384}, | 132 | {0x3243103C, "Smart Array P410", &SA5_access}, |
134 | {0x3245103C, "Smart Array P410i", &SA5_access, 384}, | 133 | {0x3245103C, "Smart Array P410i", &SA5_access}, |
135 | {0x3247103C, "Smart Array P411", &SA5_access, 384}, | 134 | {0x3247103C, "Smart Array P411", &SA5_access}, |
136 | {0x3249103C, "Smart Array P812", &SA5_access, 384}, | 135 | {0x3249103C, "Smart Array P812", &SA5_access}, |
137 | {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, | 136 | {0xFFFF103C, "Unknown Smart Array", &SA5_access}, |
138 | }; | 137 | }; |
139 | 138 | ||
140 | /* How long to wait (in milliseconds) for board to go into simple mode */ | 139 | /* How long to wait (in milliseconds) for board to go into simple mode */ |
@@ -160,7 +159,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
160 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 159 | static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
161 | 160 | ||
162 | static int cciss_revalidate(struct gendisk *disk); | 161 | static int cciss_revalidate(struct gendisk *disk); |
163 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk); | 162 | static int rebuild_lun_table(ctlr_info_t *h, int first_time); |
164 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | 163 | static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, |
165 | int clear_all); | 164 | int clear_all); |
166 | 165 | ||
@@ -172,7 +171,6 @@ static void cciss_geometry_inquiry(int ctlr, int logvol, | |||
172 | int withirq, sector_t total_size, | 171 | int withirq, sector_t total_size, |
173 | unsigned int block_size, InquiryData_struct *inq_buff, | 172 | unsigned int block_size, InquiryData_struct *inq_buff, |
174 | drive_info_struct *drv); | 173 | drive_info_struct *drv); |
175 | static void cciss_getgeometry(int cntl_num); | ||
176 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, | 174 | static void __devinit cciss_interrupt_mode(ctlr_info_t *, struct pci_dev *, |
177 | __u32); | 175 | __u32); |
178 | static void start_io(ctlr_info_t *h); | 176 | static void start_io(ctlr_info_t *h); |
@@ -930,8 +928,10 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
930 | return 0; | 928 | return 0; |
931 | } | 929 | } |
932 | 930 | ||
931 | case CCISS_DEREGDISK: | ||
932 | case CCISS_REGNEWD: | ||
933 | case CCISS_REVALIDVOLS: | 933 | case CCISS_REVALIDVOLS: |
934 | return rebuild_lun_table(host, NULL); | 934 | return rebuild_lun_table(host, 0); |
935 | 935 | ||
936 | case CCISS_GETLUNINFO:{ | 936 | case CCISS_GETLUNINFO:{ |
937 | LogvolInfo_struct luninfo; | 937 | LogvolInfo_struct luninfo; |
@@ -944,12 +944,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
944 | return -EFAULT; | 944 | return -EFAULT; |
945 | return 0; | 945 | return 0; |
946 | } | 946 | } |
947 | case CCISS_DEREGDISK: | ||
948 | return rebuild_lun_table(host, disk); | ||
949 | |||
950 | case CCISS_REGNEWD: | ||
951 | return rebuild_lun_table(host, NULL); | ||
952 | |||
953 | case CCISS_PASSTHRU: | 947 | case CCISS_PASSTHRU: |
954 | { | 948 | { |
955 | IOCTL_Command_struct iocommand; | 949 | IOCTL_Command_struct iocommand; |
@@ -1135,7 +1129,7 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, | |||
1135 | if (ioc->Request.Type.Direction == XFER_WRITE) { | 1129 | if (ioc->Request.Type.Direction == XFER_WRITE) { |
1136 | if (copy_from_user | 1130 | if (copy_from_user |
1137 | (buff[sg_used], data_ptr, sz)) { | 1131 | (buff[sg_used], data_ptr, sz)) { |
1138 | status = -ENOMEM; | 1132 | status = -EFAULT; |
1139 | goto cleanup1; | 1133 | goto cleanup1; |
1140 | } | 1134 | } |
1141 | } else { | 1135 | } else { |
@@ -1293,8 +1287,6 @@ static void cciss_check_queues(ctlr_info_t *h) | |||
1293 | h->next_to_run = curr_queue; | 1287 | h->next_to_run = curr_queue; |
1294 | break; | 1288 | break; |
1295 | } | 1289 | } |
1296 | } else { | ||
1297 | curr_queue = (curr_queue + 1) % (h->highest_lun + 1); | ||
1298 | } | 1290 | } |
1299 | } | 1291 | } |
1300 | } | 1292 | } |
@@ -1333,15 +1325,84 @@ static void cciss_softirq_done(struct request *rq) | |||
1333 | spin_unlock_irqrestore(&h->lock, flags); | 1325 | spin_unlock_irqrestore(&h->lock, flags); |
1334 | } | 1326 | } |
1335 | 1327 | ||
1328 | /* This function gets the serial number of a logical drive via | ||
1329 | * inquiry page 0x83. Serial no. is 16 bytes. If the serial | ||
1330 | * number cannot be had, for whatever reason, 16 bytes of 0xff | ||
1331 | * are returned instead. | ||
1332 | */ | ||
1333 | static void cciss_get_serial_no(int ctlr, int logvol, int withirq, | ||
1334 | unsigned char *serial_no, int buflen) | ||
1335 | { | ||
1336 | #define PAGE_83_INQ_BYTES 64 | ||
1337 | int rc; | ||
1338 | unsigned char *buf; | ||
1339 | |||
1340 | if (buflen > 16) | ||
1341 | buflen = 16; | ||
1342 | memset(serial_no, 0xff, buflen); | ||
1343 | buf = kzalloc(PAGE_83_INQ_BYTES, GFP_KERNEL); | ||
1344 | if (!buf) | ||
1345 | return; | ||
1346 | memset(serial_no, 0, buflen); | ||
1347 | if (withirq) | ||
1348 | rc = sendcmd_withirq(CISS_INQUIRY, ctlr, buf, | ||
1349 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, TYPE_CMD); | ||
1350 | else | ||
1351 | rc = sendcmd(CISS_INQUIRY, ctlr, buf, | ||
1352 | PAGE_83_INQ_BYTES, 1, logvol, 0x83, NULL, TYPE_CMD); | ||
1353 | if (rc == IO_OK) | ||
1354 | memcpy(serial_no, &buf[8], buflen); | ||
1355 | kfree(buf); | ||
1356 | return; | ||
1357 | } | ||
1358 | |||
1359 | static void cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, | ||
1360 | int drv_index) | ||
1361 | { | ||
1362 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | ||
1363 | sprintf(disk->disk_name, "cciss/c%dd%d", h->ctlr, drv_index); | ||
1364 | disk->major = h->major; | ||
1365 | disk->first_minor = drv_index << NWD_SHIFT; | ||
1366 | disk->fops = &cciss_fops; | ||
1367 | disk->private_data = &h->drv[drv_index]; | ||
1368 | |||
1369 | /* Set up queue information */ | ||
1370 | blk_queue_bounce_limit(disk->queue, h->pdev->dma_mask); | ||
1371 | |||
1372 | /* This is a hardware imposed limit. */ | ||
1373 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1374 | |||
1375 | /* This is a limit in the driver and could be eliminated. */ | ||
1376 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1377 | |||
1378 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1379 | |||
1380 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1381 | |||
1382 | disk->queue->queuedata = h; | ||
1383 | |||
1384 | blk_queue_hardsect_size(disk->queue, | ||
1385 | h->drv[drv_index].block_size); | ||
1386 | |||
1387 | /* Make sure all queue data is written out before */ | ||
1388 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1389 | /* allows the interrupt handler to start the queue */ | ||
1390 | wmb(); | ||
1391 | h->drv[drv_index].queue = disk->queue; | ||
1392 | add_disk(disk); | ||
1393 | } | ||
1394 | |||
1336 | /* This function will check the usage_count of the drive to be updated/added. | 1395 | /* This function will check the usage_count of the drive to be updated/added. |
1337 | * If the usage_count is zero then the drive information will be updated and | 1396 | * If the usage_count is zero and it is a heretofore unknown drive, or, |
1338 | * the disk will be re-registered with the kernel. If not then it will be | 1397 | * the drive's capacity, geometry, or serial number has changed, |
1339 | * left alone for the next reboot. The exception to this is disk 0 which | 1398 | * then the drive information will be updated and the disk will be |
1340 | * will always be left registered with the kernel since it is also the | 1399 | * re-registered with the kernel. If these conditions don't hold, |
1341 | * controller node. Any changes to disk 0 will show up on the next | 1400 | * then it will be left alone for the next reboot. The exception to this |
1342 | * reboot. | 1401 | * is disk 0 which will always be left registered with the kernel since it |
1402 | * is also the controller node. Any changes to disk 0 will show up on | ||
1403 | * the next reboot. | ||
1343 | */ | 1404 | */ |
1344 | static void cciss_update_drive_info(int ctlr, int drv_index) | 1405 | static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) |
1345 | { | 1406 | { |
1346 | ctlr_info_t *h = hba[ctlr]; | 1407 | ctlr_info_t *h = hba[ctlr]; |
1347 | struct gendisk *disk; | 1408 | struct gendisk *disk; |
@@ -1350,16 +1411,81 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1350 | sector_t total_size; | 1411 | sector_t total_size; |
1351 | unsigned long flags = 0; | 1412 | unsigned long flags = 0; |
1352 | int ret = 0; | 1413 | int ret = 0; |
1414 | drive_info_struct *drvinfo; | ||
1415 | int was_only_controller_node; | ||
1416 | |||
1417 | /* Get information about the disk and modify the driver structure */ | ||
1418 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
1419 | drvinfo = kmalloc(sizeof(*drvinfo), GFP_KERNEL); | ||
1420 | if (inq_buff == NULL || drvinfo == NULL) | ||
1421 | goto mem_msg; | ||
1422 | |||
1423 | /* See if we're trying to update the "controller node" | ||
1424 | * this will happen the when the first logical drive gets | ||
1425 | * created by ACU. | ||
1426 | */ | ||
1427 | was_only_controller_node = (drv_index == 0 && | ||
1428 | h->drv[0].raid_level == -1); | ||
1353 | 1429 | ||
1354 | /* if the disk already exists then deregister it before proceeding */ | 1430 | /* testing to see if 16-byte CDBs are already being used */ |
1355 | if (h->drv[drv_index].raid_level != -1) { | 1431 | if (h->cciss_read == CCISS_READ_16) { |
1432 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | ||
1433 | &total_size, &block_size); | ||
1434 | |||
1435 | } else { | ||
1436 | cciss_read_capacity(ctlr, drv_index, 1, | ||
1437 | &total_size, &block_size); | ||
1438 | |||
1439 | /* if read_capacity returns all F's this volume is >2TB */ | ||
1440 | /* in size so we switch to 16-byte CDB's for all */ | ||
1441 | /* read/write ops */ | ||
1442 | if (total_size == 0xFFFFFFFFULL) { | ||
1443 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
1444 | &total_size, &block_size); | ||
1445 | h->cciss_read = CCISS_READ_16; | ||
1446 | h->cciss_write = CCISS_WRITE_16; | ||
1447 | } else { | ||
1448 | h->cciss_read = CCISS_READ_10; | ||
1449 | h->cciss_write = CCISS_WRITE_10; | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1454 | inq_buff, drvinfo); | ||
1455 | drvinfo->block_size = block_size; | ||
1456 | drvinfo->nr_blocks = total_size + 1; | ||
1457 | |||
1458 | cciss_get_serial_no(ctlr, drv_index, 1, drvinfo->serial_no, | ||
1459 | sizeof(drvinfo->serial_no)); | ||
1460 | |||
1461 | /* Is it the same disk we already know, and nothing's changed? */ | ||
1462 | if (h->drv[drv_index].raid_level != -1 && | ||
1463 | ((memcmp(drvinfo->serial_no, | ||
1464 | h->drv[drv_index].serial_no, 16) == 0) && | ||
1465 | drvinfo->block_size == h->drv[drv_index].block_size && | ||
1466 | drvinfo->nr_blocks == h->drv[drv_index].nr_blocks && | ||
1467 | drvinfo->heads == h->drv[drv_index].heads && | ||
1468 | drvinfo->sectors == h->drv[drv_index].sectors && | ||
1469 | drvinfo->cylinders == h->drv[drv_index].cylinders)) | ||
1470 | /* The disk is unchanged, nothing to update */ | ||
1471 | goto freeret; | ||
1472 | |||
1473 | /* If we get here it's not the same disk, or something's changed, | ||
1474 | * so we need to * deregister it, and re-register it, if it's not | ||
1475 | * in use. | ||
1476 | * If the disk already exists then deregister it before proceeding | ||
1477 | * (unless it's the first disk (for the controller node). | ||
1478 | */ | ||
1479 | if (h->drv[drv_index].raid_level != -1 && drv_index != 0) { | ||
1480 | printk(KERN_WARNING "disk %d has changed.\n", drv_index); | ||
1356 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1481 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1357 | h->drv[drv_index].busy_configuring = 1; | 1482 | h->drv[drv_index].busy_configuring = 1; |
1358 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 1483 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
1359 | 1484 | ||
1360 | /* deregister_disk sets h->drv[drv_index].queue = NULL */ | 1485 | /* deregister_disk sets h->drv[drv_index].queue = NULL |
1361 | /* which keeps the interrupt handler from starting */ | 1486 | * which keeps the interrupt handler from starting |
1362 | /* the queue. */ | 1487 | * the queue. |
1488 | */ | ||
1363 | ret = deregister_disk(h->gendisk[drv_index], | 1489 | ret = deregister_disk(h->gendisk[drv_index], |
1364 | &h->drv[drv_index], 0); | 1490 | &h->drv[drv_index], 0); |
1365 | h->drv[drv_index].busy_configuring = 0; | 1491 | h->drv[drv_index].busy_configuring = 0; |
@@ -1367,81 +1493,37 @@ static void cciss_update_drive_info(int ctlr, int drv_index) | |||
1367 | 1493 | ||
1368 | /* If the disk is in use return */ | 1494 | /* If the disk is in use return */ |
1369 | if (ret) | 1495 | if (ret) |
1370 | return; | 1496 | goto freeret; |
1371 | |||
1372 | /* Get information about the disk and modify the driver structure */ | ||
1373 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
1374 | if (inq_buff == NULL) | ||
1375 | goto mem_msg; | ||
1376 | 1497 | ||
1377 | /* testing to see if 16-byte CDBs are already being used */ | 1498 | /* Save the new information from cciss_geometry_inquiry |
1378 | if (h->cciss_read == CCISS_READ_16) { | 1499 | * and serial number inquiry. |
1379 | cciss_read_capacity_16(h->ctlr, drv_index, 1, | 1500 | */ |
1380 | &total_size, &block_size); | 1501 | h->drv[drv_index].block_size = drvinfo->block_size; |
1381 | goto geo_inq; | 1502 | h->drv[drv_index].nr_blocks = drvinfo->nr_blocks; |
1382 | } | 1503 | h->drv[drv_index].heads = drvinfo->heads; |
1383 | 1504 | h->drv[drv_index].sectors = drvinfo->sectors; | |
1384 | cciss_read_capacity(ctlr, drv_index, 1, | 1505 | h->drv[drv_index].cylinders = drvinfo->cylinders; |
1385 | &total_size, &block_size); | 1506 | h->drv[drv_index].raid_level = drvinfo->raid_level; |
1386 | 1507 | memcpy(h->drv[drv_index].serial_no, drvinfo->serial_no, 16); | |
1387 | /* if read_capacity returns all F's this volume is >2TB in size */ | ||
1388 | /* so we switch to 16-byte CDB's for all read/write ops */ | ||
1389 | if (total_size == 0xFFFFFFFFULL) { | ||
1390 | cciss_read_capacity_16(ctlr, drv_index, 1, | ||
1391 | &total_size, &block_size); | ||
1392 | h->cciss_read = CCISS_READ_16; | ||
1393 | h->cciss_write = CCISS_WRITE_16; | ||
1394 | } else { | ||
1395 | h->cciss_read = CCISS_READ_10; | ||
1396 | h->cciss_write = CCISS_WRITE_10; | ||
1397 | } | ||
1398 | geo_inq: | ||
1399 | cciss_geometry_inquiry(ctlr, drv_index, 1, total_size, block_size, | ||
1400 | inq_buff, &h->drv[drv_index]); | ||
1401 | 1508 | ||
1402 | ++h->num_luns; | 1509 | ++h->num_luns; |
1403 | disk = h->gendisk[drv_index]; | 1510 | disk = h->gendisk[drv_index]; |
1404 | set_capacity(disk, h->drv[drv_index].nr_blocks); | 1511 | set_capacity(disk, h->drv[drv_index].nr_blocks); |
1405 | 1512 | ||
1406 | /* if it's the controller it's already added */ | 1513 | /* If it's not disk 0 (drv_index != 0) |
1407 | if (drv_index) { | 1514 | * or if it was disk 0, but there was previously |
1408 | disk->queue = blk_init_queue(do_cciss_request, &h->lock); | 1515 | * no actual corresponding configured logical drive |
1409 | sprintf(disk->disk_name, "cciss/c%dd%d", ctlr, drv_index); | 1516 | * (raid_leve == -1) then we want to update the |
1410 | disk->major = h->major; | 1517 | * logical drive's information. |
1411 | disk->first_minor = drv_index << NWD_SHIFT; | 1518 | */ |
1412 | disk->fops = &cciss_fops; | 1519 | if (drv_index || first_time) |
1413 | disk->private_data = &h->drv[drv_index]; | 1520 | cciss_add_disk(h, disk, drv_index); |
1414 | |||
1415 | /* Set up queue information */ | ||
1416 | blk_queue_bounce_limit(disk->queue, hba[ctlr]->pdev->dma_mask); | ||
1417 | |||
1418 | /* This is a hardware imposed limit. */ | ||
1419 | blk_queue_max_hw_segments(disk->queue, MAXSGENTRIES); | ||
1420 | |||
1421 | /* This is a limit in the driver and could be eliminated. */ | ||
1422 | blk_queue_max_phys_segments(disk->queue, MAXSGENTRIES); | ||
1423 | |||
1424 | blk_queue_max_sectors(disk->queue, h->cciss_max_sectors); | ||
1425 | |||
1426 | blk_queue_softirq_done(disk->queue, cciss_softirq_done); | ||
1427 | |||
1428 | disk->queue->queuedata = hba[ctlr]; | ||
1429 | |||
1430 | blk_queue_hardsect_size(disk->queue, | ||
1431 | hba[ctlr]->drv[drv_index].block_size); | ||
1432 | |||
1433 | /* Make sure all queue data is written out before */ | ||
1434 | /* setting h->drv[drv_index].queue, as setting this */ | ||
1435 | /* allows the interrupt handler to start the queue */ | ||
1436 | wmb(); | ||
1437 | h->drv[drv_index].queue = disk->queue; | ||
1438 | add_disk(disk); | ||
1439 | } | ||
1440 | 1521 | ||
1441 | freeret: | 1522 | freeret: |
1442 | kfree(inq_buff); | 1523 | kfree(inq_buff); |
1524 | kfree(drvinfo); | ||
1443 | return; | 1525 | return; |
1444 | mem_msg: | 1526 | mem_msg: |
1445 | printk(KERN_ERR "cciss: out of memory\n"); | 1527 | printk(KERN_ERR "cciss: out of memory\n"); |
1446 | goto freeret; | 1528 | goto freeret; |
1447 | } | 1529 | } |
@@ -1451,21 +1533,91 @@ geo_inq: | |||
1451 | * where new drives will be added. If the index to be returned is greater | 1533 | * where new drives will be added. If the index to be returned is greater |
1452 | * than the highest_lun index for the controller then highest_lun is set | 1534 | * than the highest_lun index for the controller then highest_lun is set |
1453 | * to this new index. If there are no available indexes then -1 is returned. | 1535 | * to this new index. If there are no available indexes then -1 is returned. |
1536 | * "controller_node" is used to know if this is a real logical drive, or just | ||
1537 | * the controller node, which determines if this counts towards highest_lun. | ||
1454 | */ | 1538 | */ |
1455 | static int cciss_find_free_drive_index(int ctlr) | 1539 | static int cciss_find_free_drive_index(int ctlr, int controller_node) |
1456 | { | 1540 | { |
1457 | int i; | 1541 | int i; |
1458 | 1542 | ||
1459 | for (i = 0; i < CISS_MAX_LUN; i++) { | 1543 | for (i = 0; i < CISS_MAX_LUN; i++) { |
1460 | if (hba[ctlr]->drv[i].raid_level == -1) { | 1544 | if (hba[ctlr]->drv[i].raid_level == -1) { |
1461 | if (i > hba[ctlr]->highest_lun) | 1545 | if (i > hba[ctlr]->highest_lun) |
1462 | hba[ctlr]->highest_lun = i; | 1546 | if (!controller_node) |
1547 | hba[ctlr]->highest_lun = i; | ||
1463 | return i; | 1548 | return i; |
1464 | } | 1549 | } |
1465 | } | 1550 | } |
1466 | return -1; | 1551 | return -1; |
1467 | } | 1552 | } |
1468 | 1553 | ||
1554 | /* cciss_add_gendisk finds a free hba[]->drv structure | ||
1555 | * and allocates a gendisk if needed, and sets the lunid | ||
1556 | * in the drvinfo structure. It returns the index into | ||
1557 | * the ->drv[] array, or -1 if none are free. | ||
1558 | * is_controller_node indicates whether highest_lun should | ||
1559 | * count this disk, or if it's only being added to provide | ||
1560 | * a means to talk to the controller in case no logical | ||
1561 | * drives have yet been configured. | ||
1562 | */ | ||
1563 | static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) | ||
1564 | { | ||
1565 | int drv_index; | ||
1566 | |||
1567 | drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); | ||
1568 | if (drv_index == -1) | ||
1569 | return -1; | ||
1570 | /*Check if the gendisk needs to be allocated */ | ||
1571 | if (!h->gendisk[drv_index]) { | ||
1572 | h->gendisk[drv_index] = | ||
1573 | alloc_disk(1 << NWD_SHIFT); | ||
1574 | if (!h->gendisk[drv_index]) { | ||
1575 | printk(KERN_ERR "cciss%d: could not " | ||
1576 | "allocate a new disk %d\n", | ||
1577 | h->ctlr, drv_index); | ||
1578 | return -1; | ||
1579 | } | ||
1580 | } | ||
1581 | h->drv[drv_index].LunID = lunid; | ||
1582 | |||
1583 | /* Don't need to mark this busy because nobody */ | ||
1584 | /* else knows about this disk yet to contend */ | ||
1585 | /* for access to it. */ | ||
1586 | h->drv[drv_index].busy_configuring = 0; | ||
1587 | wmb(); | ||
1588 | return drv_index; | ||
1589 | } | ||
1590 | |||
1591 | /* This is for the special case of a controller which | ||
1592 | * has no logical drives. In this case, we still need | ||
1593 | * to register a disk so the controller can be accessed | ||
1594 | * by the Array Config Utility. | ||
1595 | */ | ||
1596 | static void cciss_add_controller_node(ctlr_info_t *h) | ||
1597 | { | ||
1598 | struct gendisk *disk; | ||
1599 | int drv_index; | ||
1600 | |||
1601 | if (h->gendisk[0] != NULL) /* already did this? Then bail. */ | ||
1602 | return; | ||
1603 | |||
1604 | drv_index = cciss_add_gendisk(h, 0, 1); | ||
1605 | if (drv_index == -1) { | ||
1606 | printk(KERN_WARNING "cciss%d: could not " | ||
1607 | "add disk 0.\n", h->ctlr); | ||
1608 | return; | ||
1609 | } | ||
1610 | h->drv[drv_index].block_size = 512; | ||
1611 | h->drv[drv_index].nr_blocks = 0; | ||
1612 | h->drv[drv_index].heads = 0; | ||
1613 | h->drv[drv_index].sectors = 0; | ||
1614 | h->drv[drv_index].cylinders = 0; | ||
1615 | h->drv[drv_index].raid_level = -1; | ||
1616 | memset(h->drv[drv_index].serial_no, 0, 16); | ||
1617 | disk = h->gendisk[drv_index]; | ||
1618 | cciss_add_disk(h, disk, drv_index); | ||
1619 | } | ||
1620 | |||
1469 | /* This function will add and remove logical drives from the Logical | 1621 | /* This function will add and remove logical drives from the Logical |
1470 | * drive array of the controller and maintain persistency of ordering | 1622 | * drive array of the controller and maintain persistency of ordering |
1471 | * so that mount points are preserved until the next reboot. This allows | 1623 | * so that mount points are preserved until the next reboot. This allows |
@@ -1473,15 +1625,12 @@ static int cciss_find_free_drive_index(int ctlr) | |||
1473 | * without a re-ordering of those drives. | 1625 | * without a re-ordering of those drives. |
1474 | * INPUT | 1626 | * INPUT |
1475 | * h = The controller to perform the operations on | 1627 | * h = The controller to perform the operations on |
1476 | * del_disk = The disk to remove if specified. If the value given | ||
1477 | * is NULL then no disk is removed. | ||
1478 | */ | 1628 | */ |
1479 | static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | 1629 | static int rebuild_lun_table(ctlr_info_t *h, int first_time) |
1480 | { | 1630 | { |
1481 | int ctlr = h->ctlr; | 1631 | int ctlr = h->ctlr; |
1482 | int num_luns; | 1632 | int num_luns; |
1483 | ReportLunData_struct *ld_buff = NULL; | 1633 | ReportLunData_struct *ld_buff = NULL; |
1484 | drive_info_struct *drv = NULL; | ||
1485 | int return_code; | 1634 | int return_code; |
1486 | int listlength = 0; | 1635 | int listlength = 0; |
1487 | int i; | 1636 | int i; |
@@ -1490,6 +1639,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1490 | __u32 lunid = 0; | 1639 | __u32 lunid = 0; |
1491 | unsigned long flags; | 1640 | unsigned long flags; |
1492 | 1641 | ||
1642 | if (!capable(CAP_SYS_RAWIO)) | ||
1643 | return -EPERM; | ||
1644 | |||
1493 | /* Set busy_configuring flag for this operation */ | 1645 | /* Set busy_configuring flag for this operation */ |
1494 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | 1646 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); |
1495 | if (h->busy_configuring) { | 1647 | if (h->busy_configuring) { |
@@ -1497,100 +1649,100 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1497 | return -EBUSY; | 1649 | return -EBUSY; |
1498 | } | 1650 | } |
1499 | h->busy_configuring = 1; | 1651 | h->busy_configuring = 1; |
1652 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1500 | 1653 | ||
1501 | /* if del_disk is NULL then we are being called to add a new disk | 1654 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); |
1502 | * and update the logical drive table. If it is not NULL then | 1655 | if (ld_buff == NULL) |
1503 | * we will check if the disk is in use or not. | 1656 | goto mem_msg; |
1504 | */ | ||
1505 | if (del_disk != NULL) { | ||
1506 | drv = get_drv(del_disk); | ||
1507 | drv->busy_configuring = 1; | ||
1508 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1509 | return_code = deregister_disk(del_disk, drv, 1); | ||
1510 | drv->busy_configuring = 0; | ||
1511 | h->busy_configuring = 0; | ||
1512 | return return_code; | ||
1513 | } else { | ||
1514 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1515 | if (!capable(CAP_SYS_RAWIO)) | ||
1516 | return -EPERM; | ||
1517 | 1657 | ||
1518 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | 1658 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, |
1519 | if (ld_buff == NULL) | 1659 | sizeof(ReportLunData_struct), 0, |
1520 | goto mem_msg; | 1660 | 0, 0, TYPE_CMD); |
1521 | |||
1522 | return_code = sendcmd_withirq(CISS_REPORT_LOG, ctlr, ld_buff, | ||
1523 | sizeof(ReportLunData_struct), 0, | ||
1524 | 0, 0, TYPE_CMD); | ||
1525 | |||
1526 | if (return_code == IO_OK) { | ||
1527 | listlength = | ||
1528 | be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); | ||
1529 | } else { /* reading number of logical volumes failed */ | ||
1530 | printk(KERN_WARNING "cciss: report logical volume" | ||
1531 | " command failed\n"); | ||
1532 | listlength = 0; | ||
1533 | goto freeret; | ||
1534 | } | ||
1535 | 1661 | ||
1536 | num_luns = listlength / 8; /* 8 bytes per entry */ | 1662 | if (return_code == IO_OK) |
1537 | if (num_luns > CISS_MAX_LUN) { | 1663 | listlength = be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); |
1538 | num_luns = CISS_MAX_LUN; | 1664 | else { /* reading number of logical volumes failed */ |
1539 | printk(KERN_WARNING "cciss: more luns configured" | 1665 | printk(KERN_WARNING "cciss: report logical volume" |
1540 | " on controller than can be handled by" | 1666 | " command failed\n"); |
1541 | " this driver.\n"); | 1667 | listlength = 0; |
1668 | goto freeret; | ||
1669 | } | ||
1670 | |||
1671 | num_luns = listlength / 8; /* 8 bytes per entry */ | ||
1672 | if (num_luns > CISS_MAX_LUN) { | ||
1673 | num_luns = CISS_MAX_LUN; | ||
1674 | printk(KERN_WARNING "cciss: more luns configured" | ||
1675 | " on controller than can be handled by" | ||
1676 | " this driver.\n"); | ||
1677 | } | ||
1678 | |||
1679 | if (num_luns == 0) | ||
1680 | cciss_add_controller_node(h); | ||
1681 | |||
1682 | /* Compare controller drive array to driver's drive array | ||
1683 | * to see if any drives are missing on the controller due | ||
1684 | * to action of Array Config Utility (user deletes drive) | ||
1685 | * and deregister logical drives which have disappeared. | ||
1686 | */ | ||
1687 | for (i = 0; i <= h->highest_lun; i++) { | ||
1688 | int j; | ||
1689 | drv_found = 0; | ||
1690 | for (j = 0; j < num_luns; j++) { | ||
1691 | memcpy(&lunid, &ld_buff->LUN[j][0], 4); | ||
1692 | lunid = le32_to_cpu(lunid); | ||
1693 | if (h->drv[i].LunID == lunid) { | ||
1694 | drv_found = 1; | ||
1695 | break; | ||
1696 | } | ||
1542 | } | 1697 | } |
1698 | if (!drv_found) { | ||
1699 | /* Deregister it from the OS, it's gone. */ | ||
1700 | spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); | ||
1701 | h->drv[i].busy_configuring = 1; | ||
1702 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | ||
1703 | return_code = deregister_disk(h->gendisk[i], | ||
1704 | &h->drv[i], 1); | ||
1705 | h->drv[i].busy_configuring = 0; | ||
1706 | } | ||
1707 | } | ||
1708 | |||
1709 | /* Compare controller drive array to driver's drive array. | ||
1710 | * Check for updates in the drive information and any new drives | ||
1711 | * on the controller due to ACU adding logical drives, or changing | ||
1712 | * a logical drive's size, etc. Reregister any new/changed drives | ||
1713 | */ | ||
1714 | for (i = 0; i < num_luns; i++) { | ||
1715 | int j; | ||
1543 | 1716 | ||
1544 | /* Compare controller drive array to drivers drive array. | 1717 | drv_found = 0; |
1545 | * Check for updates in the drive information and any new drives | 1718 | |
1546 | * on the controller. | 1719 | memcpy(&lunid, &ld_buff->LUN[i][0], 4); |
1720 | lunid = le32_to_cpu(lunid); | ||
1721 | |||
1722 | /* Find if the LUN is already in the drive array | ||
1723 | * of the driver. If so then update its info | ||
1724 | * if not in use. If it does not exist then find | ||
1725 | * the first free index and add it. | ||
1547 | */ | 1726 | */ |
1548 | for (i = 0; i < num_luns; i++) { | 1727 | for (j = 0; j <= h->highest_lun; j++) { |
1549 | int j; | 1728 | if (h->drv[j].raid_level != -1 && |
1550 | 1729 | h->drv[j].LunID == lunid) { | |
1551 | drv_found = 0; | 1730 | drv_index = j; |
1552 | 1731 | drv_found = 1; | |
1553 | lunid = (0xff & | 1732 | break; |
1554 | (unsigned int)(ld_buff->LUN[i][3])) << 24; | ||
1555 | lunid |= (0xff & | ||
1556 | (unsigned int)(ld_buff->LUN[i][2])) << 16; | ||
1557 | lunid |= (0xff & | ||
1558 | (unsigned int)(ld_buff->LUN[i][1])) << 8; | ||
1559 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
1560 | |||
1561 | /* Find if the LUN is already in the drive array | ||
1562 | * of the controller. If so then update its info | ||
1563 | * if not is use. If it does not exist then find | ||
1564 | * the first free index and add it. | ||
1565 | */ | ||
1566 | for (j = 0; j <= h->highest_lun; j++) { | ||
1567 | if (h->drv[j].LunID == lunid) { | ||
1568 | drv_index = j; | ||
1569 | drv_found = 1; | ||
1570 | } | ||
1571 | } | 1733 | } |
1734 | } | ||
1572 | 1735 | ||
1573 | /* check if the drive was found already in the array */ | 1736 | /* check if the drive was found already in the array */ |
1574 | if (!drv_found) { | 1737 | if (!drv_found) { |
1575 | drv_index = cciss_find_free_drive_index(ctlr); | 1738 | drv_index = cciss_add_gendisk(h, lunid, 0); |
1576 | if (drv_index == -1) | 1739 | if (drv_index == -1) |
1577 | goto freeret; | 1740 | goto freeret; |
1578 | 1741 | } | |
1579 | /*Check if the gendisk needs to be allocated */ | 1742 | cciss_update_drive_info(ctlr, drv_index, first_time); |
1580 | if (!h->gendisk[drv_index]){ | 1743 | } /* end for */ |
1581 | h->gendisk[drv_index] = alloc_disk(1 << NWD_SHIFT); | ||
1582 | if (!h->gendisk[drv_index]){ | ||
1583 | printk(KERN_ERR "cciss: could not allocate new disk %d\n", drv_index); | ||
1584 | goto mem_msg; | ||
1585 | } | ||
1586 | } | ||
1587 | } | ||
1588 | h->drv[drv_index].LunID = lunid; | ||
1589 | cciss_update_drive_info(ctlr, drv_index); | ||
1590 | } /* end for */ | ||
1591 | } /* end else */ | ||
1592 | 1744 | ||
1593 | freeret: | 1745 | freeret: |
1594 | kfree(ld_buff); | 1746 | kfree(ld_buff); |
1595 | h->busy_configuring = 0; | 1747 | h->busy_configuring = 0; |
1596 | /* We return -1 here to tell the ACU that we have registered/updated | 1748 | /* We return -1 here to tell the ACU that we have registered/updated |
@@ -1598,8 +1750,9 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) | |||
1598 | * additional times. | 1750 | * additional times. |
1599 | */ | 1751 | */ |
1600 | return -1; | 1752 | return -1; |
1601 | mem_msg: | 1753 | mem_msg: |
1602 | printk(KERN_ERR "cciss: out of memory\n"); | 1754 | printk(KERN_ERR "cciss: out of memory\n"); |
1755 | h->busy_configuring = 0; | ||
1603 | goto freeret; | 1756 | goto freeret; |
1604 | } | 1757 | } |
1605 | 1758 | ||
@@ -1655,15 +1808,15 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1655 | * other than disk 0 we will call put_disk. We do not | 1808 | * other than disk 0 we will call put_disk. We do not |
1656 | * do this for disk 0 as we need it to be able to | 1809 | * do this for disk 0 as we need it to be able to |
1657 | * configure the controller. | 1810 | * configure the controller. |
1658 | */ | 1811 | */ |
1659 | if (clear_all){ | 1812 | if (clear_all){ |
1660 | /* This isn't pretty, but we need to find the | 1813 | /* This isn't pretty, but we need to find the |
1661 | * disk in our array and NULL our the pointer. | 1814 | * disk in our array and NULL our the pointer. |
1662 | * This is so that we will call alloc_disk if | 1815 | * This is so that we will call alloc_disk if |
1663 | * this index is used again later. | 1816 | * this index is used again later. |
1664 | */ | 1817 | */ |
1665 | for (i=0; i < CISS_MAX_LUN; i++){ | 1818 | for (i=0; i < CISS_MAX_LUN; i++){ |
1666 | if(h->gendisk[i] == disk){ | 1819 | if (h->gendisk[i] == disk) { |
1667 | h->gendisk[i] = NULL; | 1820 | h->gendisk[i] = NULL; |
1668 | break; | 1821 | break; |
1669 | } | 1822 | } |
@@ -1691,7 +1844,7 @@ static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, | |||
1691 | if (drv == h->drv + h->highest_lun) { | 1844 | if (drv == h->drv + h->highest_lun) { |
1692 | /* if so, find the new hightest lun */ | 1845 | /* if so, find the new hightest lun */ |
1693 | int i, newhighest = -1; | 1846 | int i, newhighest = -1; |
1694 | for (i = 0; i < h->highest_lun; i++) { | 1847 | for (i = 0; i <= h->highest_lun; i++) { |
1695 | /* if the disk has size > 0, it is available */ | 1848 | /* if the disk has size > 0, it is available */ |
1696 | if (h->drv[i].heads) | 1849 | if (h->drv[i].heads) |
1697 | newhighest = i; | 1850 | newhighest = i; |
@@ -3086,11 +3239,20 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3086 | print_cfg_table(c->cfgtable); | 3239 | print_cfg_table(c->cfgtable); |
3087 | #endif /* CCISS_DEBUG */ | 3240 | #endif /* CCISS_DEBUG */ |
3088 | 3241 | ||
3242 | /* Some controllers support Zero Memory Raid (ZMR). | ||
3243 | * When configured in ZMR mode the number of supported | ||
3244 | * commands drops to 64. So instead of just setting an | ||
3245 | * arbitrary value we make the driver a little smarter. | ||
3246 | * We read the config table to tell us how many commands | ||
3247 | * are supported on the controller then subtract 4 to | ||
3248 | * leave a little room for ioctl calls. | ||
3249 | */ | ||
3250 | c->max_commands = readl(&(c->cfgtable->CmdsOutMax)); | ||
3089 | for (i = 0; i < ARRAY_SIZE(products); i++) { | 3251 | for (i = 0; i < ARRAY_SIZE(products); i++) { |
3090 | if (board_id == products[i].board_id) { | 3252 | if (board_id == products[i].board_id) { |
3091 | c->product_name = products[i].product_name; | 3253 | c->product_name = products[i].product_name; |
3092 | c->access = *(products[i].access); | 3254 | c->access = *(products[i].access); |
3093 | c->nr_cmds = products[i].nr_cmds; | 3255 | c->nr_cmds = c->max_commands - 4; |
3094 | break; | 3256 | break; |
3095 | } | 3257 | } |
3096 | } | 3258 | } |
@@ -3110,7 +3272,7 @@ static int __devinit cciss_pci_init(ctlr_info_t *c, struct pci_dev *pdev) | |||
3110 | if (subsystem_vendor_id == PCI_VENDOR_ID_HP) { | 3272 | if (subsystem_vendor_id == PCI_VENDOR_ID_HP) { |
3111 | c->product_name = products[i-1].product_name; | 3273 | c->product_name = products[i-1].product_name; |
3112 | c->access = *(products[i-1].access); | 3274 | c->access = *(products[i-1].access); |
3113 | c->nr_cmds = products[i-1].nr_cmds; | 3275 | c->nr_cmds = c->max_commands - 4; |
3114 | printk(KERN_WARNING "cciss: This is an unknown " | 3276 | printk(KERN_WARNING "cciss: This is an unknown " |
3115 | "Smart Array controller.\n" | 3277 | "Smart Array controller.\n" |
3116 | "cciss: Please update to the latest driver " | 3278 | "cciss: Please update to the latest driver " |
@@ -3193,136 +3355,9 @@ err_out_free_res: | |||
3193 | return err; | 3355 | return err; |
3194 | } | 3356 | } |
3195 | 3357 | ||
3196 | /* | 3358 | /* Function to find the first free pointer into our hba[] array |
3197 | * Gets information about the local volumes attached to the controller. | 3359 | * Returns -1 if no free entries are left. |
3198 | */ | 3360 | */ |
3199 | static void cciss_getgeometry(int cntl_num) | ||
3200 | { | ||
3201 | ReportLunData_struct *ld_buff; | ||
3202 | InquiryData_struct *inq_buff; | ||
3203 | int return_code; | ||
3204 | int i; | ||
3205 | int listlength = 0; | ||
3206 | __u32 lunid = 0; | ||
3207 | unsigned block_size; | ||
3208 | sector_t total_size; | ||
3209 | |||
3210 | ld_buff = kzalloc(sizeof(ReportLunData_struct), GFP_KERNEL); | ||
3211 | if (ld_buff == NULL) { | ||
3212 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3213 | return; | ||
3214 | } | ||
3215 | inq_buff = kmalloc(sizeof(InquiryData_struct), GFP_KERNEL); | ||
3216 | if (inq_buff == NULL) { | ||
3217 | printk(KERN_ERR "cciss: out of memory\n"); | ||
3218 | kfree(ld_buff); | ||
3219 | return; | ||
3220 | } | ||
3221 | /* Get the firmware version */ | ||
3222 | return_code = sendcmd(CISS_INQUIRY, cntl_num, inq_buff, | ||
3223 | sizeof(InquiryData_struct), 0, 0, 0, NULL, | ||
3224 | TYPE_CMD); | ||
3225 | if (return_code == IO_OK) { | ||
3226 | hba[cntl_num]->firm_ver[0] = inq_buff->data_byte[32]; | ||
3227 | hba[cntl_num]->firm_ver[1] = inq_buff->data_byte[33]; | ||
3228 | hba[cntl_num]->firm_ver[2] = inq_buff->data_byte[34]; | ||
3229 | hba[cntl_num]->firm_ver[3] = inq_buff->data_byte[35]; | ||
3230 | } else { /* send command failed */ | ||
3231 | |||
3232 | printk(KERN_WARNING "cciss: unable to determine firmware" | ||
3233 | " version of controller\n"); | ||
3234 | } | ||
3235 | /* Get the number of logical volumes */ | ||
3236 | return_code = sendcmd(CISS_REPORT_LOG, cntl_num, ld_buff, | ||
3237 | sizeof(ReportLunData_struct), 0, 0, 0, NULL, | ||
3238 | TYPE_CMD); | ||
3239 | |||
3240 | if (return_code == IO_OK) { | ||
3241 | #ifdef CCISS_DEBUG | ||
3242 | printk("LUN Data\n--------------------------\n"); | ||
3243 | #endif /* CCISS_DEBUG */ | ||
3244 | |||
3245 | listlength |= | ||
3246 | (0xff & (unsigned int)(ld_buff->LUNListLength[0])) << 24; | ||
3247 | listlength |= | ||
3248 | (0xff & (unsigned int)(ld_buff->LUNListLength[1])) << 16; | ||
3249 | listlength |= | ||
3250 | (0xff & (unsigned int)(ld_buff->LUNListLength[2])) << 8; | ||
3251 | listlength |= 0xff & (unsigned int)(ld_buff->LUNListLength[3]); | ||
3252 | } else { /* reading number of logical volumes failed */ | ||
3253 | |||
3254 | printk(KERN_WARNING "cciss: report logical volume" | ||
3255 | " command failed\n"); | ||
3256 | listlength = 0; | ||
3257 | } | ||
3258 | hba[cntl_num]->num_luns = listlength / 8; // 8 bytes pre entry | ||
3259 | if (hba[cntl_num]->num_luns > CISS_MAX_LUN) { | ||
3260 | printk(KERN_ERR | ||
3261 | "ciss: only %d number of logical volumes supported\n", | ||
3262 | CISS_MAX_LUN); | ||
3263 | hba[cntl_num]->num_luns = CISS_MAX_LUN; | ||
3264 | } | ||
3265 | #ifdef CCISS_DEBUG | ||
3266 | printk(KERN_DEBUG "Length = %x %x %x %x = %d\n", | ||
3267 | ld_buff->LUNListLength[0], ld_buff->LUNListLength[1], | ||
3268 | ld_buff->LUNListLength[2], ld_buff->LUNListLength[3], | ||
3269 | hba[cntl_num]->num_luns); | ||
3270 | #endif /* CCISS_DEBUG */ | ||
3271 | |||
3272 | hba[cntl_num]->highest_lun = hba[cntl_num]->num_luns - 1; | ||
3273 | for (i = 0; i < CISS_MAX_LUN; i++) { | ||
3274 | if (i < hba[cntl_num]->num_luns) { | ||
3275 | lunid = (0xff & (unsigned int)(ld_buff->LUN[i][3])) | ||
3276 | << 24; | ||
3277 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][2])) | ||
3278 | << 16; | ||
3279 | lunid |= (0xff & (unsigned int)(ld_buff->LUN[i][1])) | ||
3280 | << 8; | ||
3281 | lunid |= 0xff & (unsigned int)(ld_buff->LUN[i][0]); | ||
3282 | |||
3283 | hba[cntl_num]->drv[i].LunID = lunid; | ||
3284 | |||
3285 | #ifdef CCISS_DEBUG | ||
3286 | printk(KERN_DEBUG "LUN[%d]: %x %x %x %x = %x\n", i, | ||
3287 | ld_buff->LUN[i][0], ld_buff->LUN[i][1], | ||
3288 | ld_buff->LUN[i][2], ld_buff->LUN[i][3], | ||
3289 | hba[cntl_num]->drv[i].LunID); | ||
3290 | #endif /* CCISS_DEBUG */ | ||
3291 | |||
3292 | /* testing to see if 16-byte CDBs are already being used */ | ||
3293 | if(hba[cntl_num]->cciss_read == CCISS_READ_16) { | ||
3294 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3295 | &total_size, &block_size); | ||
3296 | goto geo_inq; | ||
3297 | } | ||
3298 | cciss_read_capacity(cntl_num, i, 0, &total_size, &block_size); | ||
3299 | |||
3300 | /* If read_capacity returns all F's the logical is >2TB */ | ||
3301 | /* so we switch to 16-byte CDBs for all read/write ops */ | ||
3302 | if(total_size == 0xFFFFFFFFULL) { | ||
3303 | cciss_read_capacity_16(cntl_num, i, 0, | ||
3304 | &total_size, &block_size); | ||
3305 | hba[cntl_num]->cciss_read = CCISS_READ_16; | ||
3306 | hba[cntl_num]->cciss_write = CCISS_WRITE_16; | ||
3307 | } else { | ||
3308 | hba[cntl_num]->cciss_read = CCISS_READ_10; | ||
3309 | hba[cntl_num]->cciss_write = CCISS_WRITE_10; | ||
3310 | } | ||
3311 | geo_inq: | ||
3312 | cciss_geometry_inquiry(cntl_num, i, 0, total_size, | ||
3313 | block_size, inq_buff, | ||
3314 | &hba[cntl_num]->drv[i]); | ||
3315 | } else { | ||
3316 | /* initialize raid_level to indicate a free space */ | ||
3317 | hba[cntl_num]->drv[i].raid_level = -1; | ||
3318 | } | ||
3319 | } | ||
3320 | kfree(ld_buff); | ||
3321 | kfree(inq_buff); | ||
3322 | } | ||
3323 | |||
3324 | /* Function to find the first free pointer into our hba[] array */ | ||
3325 | /* Returns -1 if no free entries are left. */ | ||
3326 | static int alloc_cciss_hba(void) | 3361 | static int alloc_cciss_hba(void) |
3327 | { | 3362 | { |
3328 | int i; | 3363 | int i; |
@@ -3334,11 +3369,6 @@ static int alloc_cciss_hba(void) | |||
3334 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); | 3369 | p = kzalloc(sizeof(ctlr_info_t), GFP_KERNEL); |
3335 | if (!p) | 3370 | if (!p) |
3336 | goto Enomem; | 3371 | goto Enomem; |
3337 | p->gendisk[0] = alloc_disk(1 << NWD_SHIFT); | ||
3338 | if (!p->gendisk[0]) { | ||
3339 | kfree(p); | ||
3340 | goto Enomem; | ||
3341 | } | ||
3342 | hba[i] = p; | 3372 | hba[i] = p; |
3343 | return i; | 3373 | return i; |
3344 | } | 3374 | } |
@@ -3430,8 +3460,8 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3430 | hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not"); | 3460 | hba[i]->intr[SIMPLE_MODE_INT], dac ? "" : " not"); |
3431 | 3461 | ||
3432 | hba[i]->cmd_pool_bits = | 3462 | hba[i]->cmd_pool_bits = |
3433 | kmalloc(((hba[i]->nr_cmds + BITS_PER_LONG - | 3463 | kmalloc(DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) |
3434 | 1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL); | 3464 | * sizeof(unsigned long), GFP_KERNEL); |
3435 | hba[i]->cmd_pool = (CommandList_struct *) | 3465 | hba[i]->cmd_pool = (CommandList_struct *) |
3436 | pci_alloc_consistent(hba[i]->pdev, | 3466 | pci_alloc_consistent(hba[i]->pdev, |
3437 | hba[i]->nr_cmds * sizeof(CommandList_struct), | 3467 | hba[i]->nr_cmds * sizeof(CommandList_struct), |
@@ -3463,14 +3493,16 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3463 | /* command and error info recs zeroed out before | 3493 | /* command and error info recs zeroed out before |
3464 | they are used */ | 3494 | they are used */ |
3465 | memset(hba[i]->cmd_pool_bits, 0, | 3495 | memset(hba[i]->cmd_pool_bits, 0, |
3466 | ((hba[i]->nr_cmds + BITS_PER_LONG - | 3496 | DIV_ROUND_UP(hba[i]->nr_cmds, BITS_PER_LONG) |
3467 | 1) / BITS_PER_LONG) * sizeof(unsigned long)); | 3497 | * sizeof(unsigned long)); |
3468 | 3498 | ||
3469 | #ifdef CCISS_DEBUG | 3499 | hba[i]->num_luns = 0; |
3470 | printk(KERN_DEBUG "Scanning for drives on controller cciss%d\n", i); | 3500 | hba[i]->highest_lun = -1; |
3471 | #endif /* CCISS_DEBUG */ | 3501 | for (j = 0; j < CISS_MAX_LUN; j++) { |
3472 | 3502 | hba[i]->drv[j].raid_level = -1; | |
3473 | cciss_getgeometry(i); | 3503 | hba[i]->drv[j].queue = NULL; |
3504 | hba[i]->gendisk[j] = NULL; | ||
3505 | } | ||
3474 | 3506 | ||
3475 | cciss_scsi_setup(i); | 3507 | cciss_scsi_setup(i); |
3476 | 3508 | ||
@@ -3483,72 +3515,10 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3483 | 3515 | ||
3484 | hba[i]->busy_initializing = 0; | 3516 | hba[i]->busy_initializing = 0; |
3485 | 3517 | ||
3486 | do { | 3518 | rebuild_lun_table(hba[i], 1); |
3487 | drive_info_struct *drv = &(hba[i]->drv[j]); | ||
3488 | struct gendisk *disk = hba[i]->gendisk[j]; | ||
3489 | struct request_queue *q; | ||
3490 | |||
3491 | /* Check if the disk was allocated already */ | ||
3492 | if (!disk){ | ||
3493 | hba[i]->gendisk[j] = alloc_disk(1 << NWD_SHIFT); | ||
3494 | disk = hba[i]->gendisk[j]; | ||
3495 | } | ||
3496 | |||
3497 | /* Check that the disk was able to be allocated */ | ||
3498 | if (!disk) { | ||
3499 | printk(KERN_ERR "cciss: unable to allocate memory for disk %d\n", j); | ||
3500 | goto clean4; | ||
3501 | } | ||
3502 | |||
3503 | q = blk_init_queue(do_cciss_request, &hba[i]->lock); | ||
3504 | if (!q) { | ||
3505 | printk(KERN_ERR | ||
3506 | "cciss: unable to allocate queue for disk %d\n", | ||
3507 | j); | ||
3508 | goto clean4; | ||
3509 | } | ||
3510 | drv->queue = q; | ||
3511 | |||
3512 | blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); | ||
3513 | |||
3514 | /* This is a hardware imposed limit. */ | ||
3515 | blk_queue_max_hw_segments(q, MAXSGENTRIES); | ||
3516 | |||
3517 | /* This is a limit in the driver and could be eliminated. */ | ||
3518 | blk_queue_max_phys_segments(q, MAXSGENTRIES); | ||
3519 | |||
3520 | blk_queue_max_sectors(q, hba[i]->cciss_max_sectors); | ||
3521 | |||
3522 | blk_queue_softirq_done(q, cciss_softirq_done); | ||
3523 | |||
3524 | q->queuedata = hba[i]; | ||
3525 | sprintf(disk->disk_name, "cciss/c%dd%d", i, j); | ||
3526 | disk->major = hba[i]->major; | ||
3527 | disk->first_minor = j << NWD_SHIFT; | ||
3528 | disk->fops = &cciss_fops; | ||
3529 | disk->queue = q; | ||
3530 | disk->private_data = drv; | ||
3531 | disk->driverfs_dev = &pdev->dev; | ||
3532 | /* we must register the controller even if no disks exist */ | ||
3533 | /* this is for the online array utilities */ | ||
3534 | if (!drv->heads && j) | ||
3535 | continue; | ||
3536 | blk_queue_hardsect_size(q, drv->block_size); | ||
3537 | set_capacity(disk, drv->nr_blocks); | ||
3538 | j++; | ||
3539 | } while (j <= hba[i]->highest_lun); | ||
3540 | |||
3541 | /* Make sure all queue data is written out before */ | ||
3542 | /* interrupt handler, triggered by add_disk, */ | ||
3543 | /* is allowed to start them. */ | ||
3544 | wmb(); | ||
3545 | |||
3546 | for (j = 0; j <= hba[i]->highest_lun; j++) | ||
3547 | add_disk(hba[i]->gendisk[j]); | ||
3548 | |||
3549 | return 1; | 3519 | return 1; |
3550 | 3520 | ||
3551 | clean4: | 3521 | clean4: |
3552 | #ifdef CONFIG_CISS_SCSI_TAPE | 3522 | #ifdef CONFIG_CISS_SCSI_TAPE |
3553 | kfree(hba[i]->scsi_rejects.complete); | 3523 | kfree(hba[i]->scsi_rejects.complete); |
3554 | #endif | 3524 | #endif |
@@ -3563,9 +3533,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, | |||
3563 | hba[i]->errinfo_pool, | 3533 | hba[i]->errinfo_pool, |
3564 | hba[i]->errinfo_pool_dhandle); | 3534 | hba[i]->errinfo_pool_dhandle); |
3565 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); | 3535 | free_irq(hba[i]->intr[SIMPLE_MODE_INT], hba[i]); |
3566 | clean2: | 3536 | clean2: |
3567 | unregister_blkdev(hba[i]->major, hba[i]->devname); | 3537 | unregister_blkdev(hba[i]->major, hba[i]->devname); |
3568 | clean1: | 3538 | clean1: |
3569 | hba[i]->busy_initializing = 0; | 3539 | hba[i]->busy_initializing = 0; |
3570 | /* cleanup any queues that may have been initialized */ | 3540 | /* cleanup any queues that may have been initialized */ |
3571 | for (j=0; j <= hba[i]->highest_lun; j++){ | 3541 | for (j=0; j <= hba[i]->highest_lun; j++){ |
@@ -3644,7 +3614,9 @@ static void __devexit cciss_remove_one(struct pci_dev *pdev) | |||
3644 | } | 3614 | } |
3645 | } | 3615 | } |
3646 | 3616 | ||
3617 | #ifdef CONFIG_CISS_SCSI_TAPE | ||
3647 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ | 3618 | cciss_unregister_scsi(i); /* unhook from SCSI subsystem */ |
3619 | #endif | ||
3648 | 3620 | ||
3649 | cciss_shutdown(pdev); | 3621 | cciss_shutdown(pdev); |
3650 | 3622 | ||
diff --git a/drivers/block/cciss.h b/drivers/block/cciss.h index b70988dd33e..24a7efa993a 100644 --- a/drivers/block/cciss.h +++ b/drivers/block/cciss.h | |||
@@ -39,6 +39,8 @@ typedef struct _drive_info_struct | |||
39 | *to prevent it from being opened or it's queue | 39 | *to prevent it from being opened or it's queue |
40 | *from being started. | 40 | *from being started. |
41 | */ | 41 | */ |
42 | __u8 serial_no[16]; /* from inquiry page 0x83, */ | ||
43 | /* not necc. null terminated. */ | ||
42 | } drive_info_struct; | 44 | } drive_info_struct; |
43 | 45 | ||
44 | #ifdef CONFIG_CISS_SCSI_TAPE | 46 | #ifdef CONFIG_CISS_SCSI_TAPE |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index e4bf9a11ca0..a3fd87b4144 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -358,25 +358,74 @@ find_bus_target_lun(int ctlr, int *bus, int *target, int *lun) | |||
358 | } | 358 | } |
359 | return (!found); | 359 | return (!found); |
360 | } | 360 | } |
361 | struct scsi2map { | ||
362 | char scsi3addr[8]; | ||
363 | int bus, target, lun; | ||
364 | }; | ||
361 | 365 | ||
362 | static int | 366 | static int |
363 | cciss_scsi_add_entry(int ctlr, int hostno, | 367 | cciss_scsi_add_entry(int ctlr, int hostno, |
364 | unsigned char *scsi3addr, int devtype) | 368 | struct cciss_scsi_dev_t *device, |
369 | struct scsi2map *added, int *nadded) | ||
365 | { | 370 | { |
366 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 371 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
367 | int n = ccissscsi[ctlr].ndevices; | 372 | int n = ccissscsi[ctlr].ndevices; |
368 | struct cciss_scsi_dev_t *sd; | 373 | struct cciss_scsi_dev_t *sd; |
374 | int i, bus, target, lun; | ||
375 | unsigned char addr1[8], addr2[8]; | ||
369 | 376 | ||
370 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 377 | if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
371 | printk("cciss%d: Too many devices, " | 378 | printk("cciss%d: Too many devices, " |
372 | "some will be inaccessible.\n", ctlr); | 379 | "some will be inaccessible.\n", ctlr); |
373 | return -1; | 380 | return -1; |
374 | } | 381 | } |
382 | |||
383 | bus = target = -1; | ||
384 | lun = 0; | ||
385 | /* Is this device a non-zero lun of a multi-lun device */ | ||
386 | /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */ | ||
387 | if (device->scsi3addr[4] != 0) { | ||
388 | /* Search through our list and find the device which */ | ||
389 | /* has the same 8 byte LUN address, excepting byte 4. */ | ||
390 | /* Assign the same bus and target for this new LUN. */ | ||
391 | /* Use the logical unit number from the firmware. */ | ||
392 | memcpy(addr1, device->scsi3addr, 8); | ||
393 | addr1[4] = 0; | ||
394 | for (i = 0; i < n; i++) { | ||
395 | sd = &ccissscsi[ctlr].dev[i]; | ||
396 | memcpy(addr2, sd->scsi3addr, 8); | ||
397 | addr2[4] = 0; | ||
398 | /* differ only in byte 4? */ | ||
399 | if (memcmp(addr1, addr2, 8) == 0) { | ||
400 | bus = sd->bus; | ||
401 | target = sd->target; | ||
402 | lun = device->scsi3addr[4]; | ||
403 | break; | ||
404 | } | ||
405 | } | ||
406 | } | ||
407 | |||
375 | sd = &ccissscsi[ctlr].dev[n]; | 408 | sd = &ccissscsi[ctlr].dev[n]; |
376 | if (find_bus_target_lun(ctlr, &sd->bus, &sd->target, &sd->lun) != 0) | 409 | if (lun == 0) { |
377 | return -1; | 410 | if (find_bus_target_lun(ctlr, |
378 | memcpy(&sd->scsi3addr[0], scsi3addr, 8); | 411 | &sd->bus, &sd->target, &sd->lun) != 0) |
379 | sd->devtype = devtype; | 412 | return -1; |
413 | } else { | ||
414 | sd->bus = bus; | ||
415 | sd->target = target; | ||
416 | sd->lun = lun; | ||
417 | } | ||
418 | added[*nadded].bus = sd->bus; | ||
419 | added[*nadded].target = sd->target; | ||
420 | added[*nadded].lun = sd->lun; | ||
421 | (*nadded)++; | ||
422 | |||
423 | memcpy(sd->scsi3addr, device->scsi3addr, 8); | ||
424 | memcpy(sd->vendor, device->vendor, sizeof(sd->vendor)); | ||
425 | memcpy(sd->revision, device->revision, sizeof(sd->revision)); | ||
426 | memcpy(sd->device_id, device->device_id, sizeof(sd->device_id)); | ||
427 | sd->devtype = device->devtype; | ||
428 | |||
380 | ccissscsi[ctlr].ndevices++; | 429 | ccissscsi[ctlr].ndevices++; |
381 | 430 | ||
382 | /* initially, (before registering with scsi layer) we don't | 431 | /* initially, (before registering with scsi layer) we don't |
@@ -390,7 +439,8 @@ cciss_scsi_add_entry(int ctlr, int hostno, | |||
390 | } | 439 | } |
391 | 440 | ||
392 | static void | 441 | static void |
393 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | 442 | cciss_scsi_remove_entry(int ctlr, int hostno, int entry, |
443 | struct scsi2map *removed, int *nremoved) | ||
394 | { | 444 | { |
395 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ | 445 | /* assumes hba[ctlr]->scsi_ctlr->lock is held */ |
396 | int i; | 446 | int i; |
@@ -398,6 +448,10 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
398 | 448 | ||
399 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; | 449 | if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return; |
400 | sd = ccissscsi[ctlr].dev[entry]; | 450 | sd = ccissscsi[ctlr].dev[entry]; |
451 | removed[*nremoved].bus = sd.bus; | ||
452 | removed[*nremoved].target = sd.target; | ||
453 | removed[*nremoved].lun = sd.lun; | ||
454 | (*nremoved)++; | ||
401 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) | 455 | for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++) |
402 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; | 456 | ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1]; |
403 | ccissscsi[ctlr].ndevices--; | 457 | ccissscsi[ctlr].ndevices--; |
@@ -417,6 +471,42 @@ cciss_scsi_remove_entry(int ctlr, int hostno, int entry) | |||
417 | (a)[1] == (b)[1] && \ | 471 | (a)[1] == (b)[1] && \ |
418 | (a)[0] == (b)[0]) | 472 | (a)[0] == (b)[0]) |
419 | 473 | ||
474 | static void fixup_botched_add(int ctlr, char *scsi3addr) | ||
475 | { | ||
476 | /* called when scsi_add_device fails in order to re-adjust */ | ||
477 | /* ccissscsi[] to match the mid layer's view. */ | ||
478 | unsigned long flags; | ||
479 | int i, j; | ||
480 | CPQ_TAPE_LOCK(ctlr, flags); | ||
481 | for (i = 0; i < ccissscsi[ctlr].ndevices; i++) { | ||
482 | if (memcmp(scsi3addr, | ||
483 | ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) { | ||
484 | for (j = i; j < ccissscsi[ctlr].ndevices-1; j++) | ||
485 | ccissscsi[ctlr].dev[j] = | ||
486 | ccissscsi[ctlr].dev[j+1]; | ||
487 | ccissscsi[ctlr].ndevices--; | ||
488 | break; | ||
489 | } | ||
490 | } | ||
491 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
492 | } | ||
493 | |||
494 | static int device_is_the_same(struct cciss_scsi_dev_t *dev1, | ||
495 | struct cciss_scsi_dev_t *dev2) | ||
496 | { | ||
497 | return dev1->devtype == dev2->devtype && | ||
498 | memcmp(dev1->scsi3addr, dev2->scsi3addr, | ||
499 | sizeof(dev1->scsi3addr)) == 0 && | ||
500 | memcmp(dev1->device_id, dev2->device_id, | ||
501 | sizeof(dev1->device_id)) == 0 && | ||
502 | memcmp(dev1->vendor, dev2->vendor, | ||
503 | sizeof(dev1->vendor)) == 0 && | ||
504 | memcmp(dev1->model, dev2->model, | ||
505 | sizeof(dev1->model)) == 0 && | ||
506 | memcmp(dev1->revision, dev2->revision, | ||
507 | sizeof(dev1->revision)) == 0; | ||
508 | } | ||
509 | |||
420 | static int | 510 | static int |
421 | adjust_cciss_scsi_table(int ctlr, int hostno, | 511 | adjust_cciss_scsi_table(int ctlr, int hostno, |
422 | struct cciss_scsi_dev_t sd[], int nsds) | 512 | struct cciss_scsi_dev_t sd[], int nsds) |
@@ -429,20 +519,40 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
429 | int i,j, found, changes=0; | 519 | int i,j, found, changes=0; |
430 | struct cciss_scsi_dev_t *csd; | 520 | struct cciss_scsi_dev_t *csd; |
431 | unsigned long flags; | 521 | unsigned long flags; |
522 | struct scsi2map *added, *removed; | ||
523 | int nadded, nremoved; | ||
524 | struct Scsi_Host *sh = NULL; | ||
525 | |||
526 | added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
527 | GFP_KERNEL); | ||
528 | removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA, | ||
529 | GFP_KERNEL); | ||
530 | |||
531 | if (!added || !removed) { | ||
532 | printk(KERN_WARNING "cciss%d: Out of memory in " | ||
533 | "adjust_cciss_scsi_table\n", ctlr); | ||
534 | goto free_and_out; | ||
535 | } | ||
432 | 536 | ||
433 | CPQ_TAPE_LOCK(ctlr, flags); | 537 | CPQ_TAPE_LOCK(ctlr, flags); |
434 | 538 | ||
539 | if (hostno != -1) /* if it's not the first time... */ | ||
540 | sh = ((struct cciss_scsi_adapter_data_t *) | ||
541 | hba[ctlr]->scsi_ctlr)->scsi_host; | ||
542 | |||
435 | /* find any devices in ccissscsi[] that are not in | 543 | /* find any devices in ccissscsi[] that are not in |
436 | sd[] and remove them from ccissscsi[] */ | 544 | sd[] and remove them from ccissscsi[] */ |
437 | 545 | ||
438 | i = 0; | 546 | i = 0; |
547 | nremoved = 0; | ||
548 | nadded = 0; | ||
439 | while(i<ccissscsi[ctlr].ndevices) { | 549 | while(i<ccissscsi[ctlr].ndevices) { |
440 | csd = &ccissscsi[ctlr].dev[i]; | 550 | csd = &ccissscsi[ctlr].dev[i]; |
441 | found=0; | 551 | found=0; |
442 | for (j=0;j<nsds;j++) { | 552 | for (j=0;j<nsds;j++) { |
443 | if (SCSI3ADDR_EQ(sd[j].scsi3addr, | 553 | if (SCSI3ADDR_EQ(sd[j].scsi3addr, |
444 | csd->scsi3addr)) { | 554 | csd->scsi3addr)) { |
445 | if (sd[j].devtype == csd->devtype) | 555 | if (device_is_the_same(&sd[j], csd)) |
446 | found=2; | 556 | found=2; |
447 | else | 557 | else |
448 | found=1; | 558 | found=1; |
@@ -455,17 +565,29 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
455 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", | 565 | /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n", |
456 | ctlr, scsi_device_type(csd->devtype), hostno, | 566 | ctlr, scsi_device_type(csd->devtype), hostno, |
457 | csd->bus, csd->target, csd->lun); */ | 567 | csd->bus, csd->target, csd->lun); */ |
458 | cciss_scsi_remove_entry(ctlr, hostno, i); | 568 | cciss_scsi_remove_entry(ctlr, hostno, i, |
459 | /* note, i not incremented */ | 569 | removed, &nremoved); |
460 | } | 570 | /* remove ^^^, hence i not incremented */ |
461 | else if (found == 1) { /* device is different kind */ | 571 | } else if (found == 1) { /* device is different in some way */ |
462 | changes++; | 572 | changes++; |
463 | printk("cciss%d: device c%db%dt%dl%d type changed " | 573 | printk("cciss%d: device c%db%dt%dl%d has changed.\n", |
464 | "(device type now %s).\n", | 574 | ctlr, hostno, csd->bus, csd->target, csd->lun); |
465 | ctlr, hostno, csd->bus, csd->target, csd->lun, | 575 | cciss_scsi_remove_entry(ctlr, hostno, i, |
466 | scsi_device_type(csd->devtype)); | 576 | removed, &nremoved); |
577 | /* remove ^^^, hence i not incremented */ | ||
578 | if (cciss_scsi_add_entry(ctlr, hostno, &sd[j], | ||
579 | added, &nadded) != 0) | ||
580 | /* we just removed one, so add can't fail. */ | ||
581 | BUG(); | ||
467 | csd->devtype = sd[j].devtype; | 582 | csd->devtype = sd[j].devtype; |
468 | i++; /* so just move along. */ | 583 | memcpy(csd->device_id, sd[j].device_id, |
584 | sizeof(csd->device_id)); | ||
585 | memcpy(csd->vendor, sd[j].vendor, | ||
586 | sizeof(csd->vendor)); | ||
587 | memcpy(csd->model, sd[j].model, | ||
588 | sizeof(csd->model)); | ||
589 | memcpy(csd->revision, sd[j].revision, | ||
590 | sizeof(csd->revision)); | ||
469 | } else /* device is same as it ever was, */ | 591 | } else /* device is same as it ever was, */ |
470 | i++; /* so just move along. */ | 592 | i++; /* so just move along. */ |
471 | } | 593 | } |
@@ -479,7 +601,7 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
479 | csd = &ccissscsi[ctlr].dev[j]; | 601 | csd = &ccissscsi[ctlr].dev[j]; |
480 | if (SCSI3ADDR_EQ(sd[i].scsi3addr, | 602 | if (SCSI3ADDR_EQ(sd[i].scsi3addr, |
481 | csd->scsi3addr)) { | 603 | csd->scsi3addr)) { |
482 | if (sd[i].devtype == csd->devtype) | 604 | if (device_is_the_same(&sd[i], csd)) |
483 | found=2; /* found device */ | 605 | found=2; /* found device */ |
484 | else | 606 | else |
485 | found=1; /* found a bug. */ | 607 | found=1; /* found a bug. */ |
@@ -488,22 +610,63 @@ adjust_cciss_scsi_table(int ctlr, int hostno, | |||
488 | } | 610 | } |
489 | if (!found) { | 611 | if (!found) { |
490 | changes++; | 612 | changes++; |
491 | if (cciss_scsi_add_entry(ctlr, hostno, | 613 | if (cciss_scsi_add_entry(ctlr, hostno, &sd[i], |
492 | &sd[i].scsi3addr[0], sd[i].devtype) != 0) | 614 | added, &nadded) != 0) |
493 | break; | 615 | break; |
494 | } else if (found == 1) { | 616 | } else if (found == 1) { |
495 | /* should never happen... */ | 617 | /* should never happen... */ |
496 | changes++; | 618 | changes++; |
497 | printk("cciss%d: device unexpectedly changed type\n", | 619 | printk(KERN_WARNING "cciss%d: device " |
498 | ctlr); | 620 | "unexpectedly changed\n", ctlr); |
499 | /* but if it does happen, we just ignore that device */ | 621 | /* but if it does happen, we just ignore that device */ |
500 | } | 622 | } |
501 | } | 623 | } |
502 | CPQ_TAPE_UNLOCK(ctlr, flags); | 624 | CPQ_TAPE_UNLOCK(ctlr, flags); |
503 | 625 | ||
504 | if (!changes) | 626 | /* Don't notify scsi mid layer of any changes the first time through */ |
505 | printk("cciss%d: No device changes detected.\n", ctlr); | 627 | /* (or if there are no changes) scsi_scan_host will do it later the */ |
628 | /* first time through. */ | ||
629 | if (hostno == -1 || !changes) | ||
630 | goto free_and_out; | ||
631 | |||
632 | /* Notify scsi mid layer of any removed devices */ | ||
633 | for (i = 0; i < nremoved; i++) { | ||
634 | struct scsi_device *sdev = | ||
635 | scsi_device_lookup(sh, removed[i].bus, | ||
636 | removed[i].target, removed[i].lun); | ||
637 | if (sdev != NULL) { | ||
638 | scsi_remove_device(sdev); | ||
639 | scsi_device_put(sdev); | ||
640 | } else { | ||
641 | /* We don't expect to get here. */ | ||
642 | /* future cmds to this device will get selection */ | ||
643 | /* timeout as if the device was gone. */ | ||
644 | printk(KERN_WARNING "cciss%d: didn't find " | ||
645 | "c%db%dt%dl%d\n for removal.", | ||
646 | ctlr, hostno, removed[i].bus, | ||
647 | removed[i].target, removed[i].lun); | ||
648 | } | ||
649 | } | ||
650 | |||
651 | /* Notify scsi mid layer of any added devices */ | ||
652 | for (i = 0; i < nadded; i++) { | ||
653 | int rc; | ||
654 | rc = scsi_add_device(sh, added[i].bus, | ||
655 | added[i].target, added[i].lun); | ||
656 | if (rc == 0) | ||
657 | continue; | ||
658 | printk(KERN_WARNING "cciss%d: scsi_add_device " | ||
659 | "c%db%dt%dl%d failed, device not added.\n", | ||
660 | ctlr, hostno, | ||
661 | added[i].bus, added[i].target, added[i].lun); | ||
662 | /* now we have to remove it from ccissscsi, */ | ||
663 | /* since it didn't get added to scsi mid layer */ | ||
664 | fixup_botched_add(ctlr, added[i].scsi3addr); | ||
665 | } | ||
506 | 666 | ||
667 | free_and_out: | ||
668 | kfree(added); | ||
669 | kfree(removed); | ||
507 | return 0; | 670 | return 0; |
508 | } | 671 | } |
509 | 672 | ||
@@ -871,7 +1034,8 @@ cciss_scsi_interpret_error(CommandList_struct *cp) | |||
871 | 1034 | ||
872 | static int | 1035 | static int |
873 | cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | 1036 | cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, |
874 | unsigned char *buf, unsigned char bufsize) | 1037 | unsigned char page, unsigned char *buf, |
1038 | unsigned char bufsize) | ||
875 | { | 1039 | { |
876 | int rc; | 1040 | int rc; |
877 | CommandList_struct *cp; | 1041 | CommandList_struct *cp; |
@@ -891,8 +1055,8 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | |||
891 | ei = cp->err_info; | 1055 | ei = cp->err_info; |
892 | 1056 | ||
893 | cdb[0] = CISS_INQUIRY; | 1057 | cdb[0] = CISS_INQUIRY; |
894 | cdb[1] = 0; | 1058 | cdb[1] = (page != 0); |
895 | cdb[2] = 0; | 1059 | cdb[2] = page; |
896 | cdb[3] = 0; | 1060 | cdb[3] = 0; |
897 | cdb[4] = bufsize; | 1061 | cdb[4] = bufsize; |
898 | cdb[5] = 0; | 1062 | cdb[5] = 0; |
@@ -912,6 +1076,25 @@ cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr, | |||
912 | return rc; | 1076 | return rc; |
913 | } | 1077 | } |
914 | 1078 | ||
1079 | /* Get the device id from inquiry page 0x83 */ | ||
1080 | static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr, | ||
1081 | unsigned char *device_id, int buflen) | ||
1082 | { | ||
1083 | int rc; | ||
1084 | unsigned char *buf; | ||
1085 | |||
1086 | if (buflen > 16) | ||
1087 | buflen = 16; | ||
1088 | buf = kzalloc(64, GFP_KERNEL); | ||
1089 | if (!buf) | ||
1090 | return -1; | ||
1091 | rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64); | ||
1092 | if (rc == 0) | ||
1093 | memcpy(device_id, &buf[8], buflen); | ||
1094 | kfree(buf); | ||
1095 | return rc != 0; | ||
1096 | } | ||
1097 | |||
915 | static int | 1098 | static int |
916 | cciss_scsi_do_report_phys_luns(ctlr_info_t *c, | 1099 | cciss_scsi_do_report_phys_luns(ctlr_info_t *c, |
917 | ReportLunData_struct *buf, int bufsize) | 1100 | ReportLunData_struct *buf, int bufsize) |
@@ -1001,25 +1184,21 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1001 | ctlr_info_t *c; | 1184 | ctlr_info_t *c; |
1002 | __u32 num_luns=0; | 1185 | __u32 num_luns=0; |
1003 | unsigned char *ch; | 1186 | unsigned char *ch; |
1004 | /* unsigned char found[CCISS_MAX_SCSI_DEVS_PER_HBA]; */ | 1187 | struct cciss_scsi_dev_t *currentsd, *this_device; |
1005 | struct cciss_scsi_dev_t currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA]; | ||
1006 | int ncurrent=0; | 1188 | int ncurrent=0; |
1007 | int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8; | 1189 | int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8; |
1008 | int i; | 1190 | int i; |
1009 | 1191 | ||
1010 | c = (ctlr_info_t *) hba[cntl_num]; | 1192 | c = (ctlr_info_t *) hba[cntl_num]; |
1011 | ld_buff = kzalloc(reportlunsize, GFP_KERNEL); | 1193 | ld_buff = kzalloc(reportlunsize, GFP_KERNEL); |
1012 | if (ld_buff == NULL) { | ||
1013 | printk(KERN_ERR "cciss: out of memory\n"); | ||
1014 | return; | ||
1015 | } | ||
1016 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); | 1194 | inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL); |
1017 | if (inq_buff == NULL) { | 1195 | currentsd = kzalloc(sizeof(*currentsd) * |
1018 | printk(KERN_ERR "cciss: out of memory\n"); | 1196 | (CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL); |
1019 | kfree(ld_buff); | 1197 | if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) { |
1020 | return; | 1198 | printk(KERN_ERR "cciss: out of memory\n"); |
1199 | goto out; | ||
1021 | } | 1200 | } |
1022 | 1201 | this_device = ¤tsd[CCISS_MAX_SCSI_DEVS_PER_HBA]; | |
1023 | if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) { | 1202 | if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) { |
1024 | ch = &ld_buff->LUNListLength[0]; | 1203 | ch = &ld_buff->LUNListLength[0]; |
1025 | num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8; | 1204 | num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8; |
@@ -1038,23 +1217,34 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1038 | 1217 | ||
1039 | 1218 | ||
1040 | /* adjust our table of devices */ | 1219 | /* adjust our table of devices */ |
1041 | for(i=0; i<num_luns; i++) | 1220 | for (i = 0; i < num_luns; i++) { |
1042 | { | ||
1043 | int devtype; | ||
1044 | |||
1045 | /* for each physical lun, do an inquiry */ | 1221 | /* for each physical lun, do an inquiry */ |
1046 | if (ld_buff->LUN[i][3] & 0xC0) continue; | 1222 | if (ld_buff->LUN[i][3] & 0xC0) continue; |
1047 | memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); | 1223 | memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE); |
1048 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); | 1224 | memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8); |
1049 | 1225 | ||
1050 | if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff, | 1226 | if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff, |
1051 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) { | 1227 | (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) |
1052 | /* Inquiry failed (msg printed already) */ | 1228 | /* Inquiry failed (msg printed already) */ |
1053 | devtype = 0; /* so we will skip this device. */ | 1229 | continue; /* so we will skip this device. */ |
1054 | } else /* what kind of device is this? */ | 1230 | |
1055 | devtype = (inq_buff[0] & 0x1f); | 1231 | this_device->devtype = (inq_buff[0] & 0x1f); |
1056 | 1232 | this_device->bus = -1; | |
1057 | switch (devtype) | 1233 | this_device->target = -1; |
1234 | this_device->lun = -1; | ||
1235 | memcpy(this_device->scsi3addr, scsi3addr, 8); | ||
1236 | memcpy(this_device->vendor, &inq_buff[8], | ||
1237 | sizeof(this_device->vendor)); | ||
1238 | memcpy(this_device->model, &inq_buff[16], | ||
1239 | sizeof(this_device->model)); | ||
1240 | memcpy(this_device->revision, &inq_buff[32], | ||
1241 | sizeof(this_device->revision)); | ||
1242 | memset(this_device->device_id, 0, | ||
1243 | sizeof(this_device->device_id)); | ||
1244 | cciss_scsi_get_device_id(hba[cntl_num], scsi3addr, | ||
1245 | this_device->device_id, sizeof(this_device->device_id)); | ||
1246 | |||
1247 | switch (this_device->devtype) | ||
1058 | { | 1248 | { |
1059 | case 0x05: /* CD-ROM */ { | 1249 | case 0x05: /* CD-ROM */ { |
1060 | 1250 | ||
@@ -1079,15 +1269,10 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1079 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { | 1269 | if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) { |
1080 | printk(KERN_INFO "cciss%d: %s ignored, " | 1270 | printk(KERN_INFO "cciss%d: %s ignored, " |
1081 | "too many devices.\n", cntl_num, | 1271 | "too many devices.\n", cntl_num, |
1082 | scsi_device_type(devtype)); | 1272 | scsi_device_type(this_device->devtype)); |
1083 | break; | 1273 | break; |
1084 | } | 1274 | } |
1085 | memcpy(¤tsd[ncurrent].scsi3addr[0], | 1275 | currentsd[ncurrent] = *this_device; |
1086 | &scsi3addr[0], 8); | ||
1087 | currentsd[ncurrent].devtype = devtype; | ||
1088 | currentsd[ncurrent].bus = -1; | ||
1089 | currentsd[ncurrent].target = -1; | ||
1090 | currentsd[ncurrent].lun = -1; | ||
1091 | ncurrent++; | 1276 | ncurrent++; |
1092 | break; | 1277 | break; |
1093 | default: | 1278 | default: |
@@ -1099,6 +1284,7 @@ cciss_update_non_disk_devices(int cntl_num, int hostno) | |||
1099 | out: | 1284 | out: |
1100 | kfree(inq_buff); | 1285 | kfree(inq_buff); |
1101 | kfree(ld_buff); | 1286 | kfree(ld_buff); |
1287 | kfree(currentsd); | ||
1102 | return; | 1288 | return; |
1103 | } | 1289 | } |
1104 | 1290 | ||
@@ -1355,32 +1541,6 @@ cciss_unregister_scsi(int ctlr) | |||
1355 | } | 1541 | } |
1356 | 1542 | ||
1357 | static int | 1543 | static int |
1358 | cciss_register_scsi(int ctlr) | ||
1359 | { | ||
1360 | unsigned long flags; | ||
1361 | |||
1362 | CPQ_TAPE_LOCK(ctlr, flags); | ||
1363 | |||
1364 | /* Since this is really a block driver, the SCSI core may not be | ||
1365 | initialized at init time, in which case, calling scsi_register_host | ||
1366 | would hang. Instead, we do it later, via /proc filesystem | ||
1367 | and rc scripts, when we know SCSI core is good to go. */ | ||
1368 | |||
1369 | /* Only register if SCSI devices are detected. */ | ||
1370 | if (ccissscsi[ctlr].ndevices != 0) { | ||
1371 | ((struct cciss_scsi_adapter_data_t *) | ||
1372 | hba[ctlr]->scsi_ctlr)->registered = 1; | ||
1373 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
1374 | return cciss_scsi_detect(ctlr); | ||
1375 | } | ||
1376 | CPQ_TAPE_UNLOCK(ctlr, flags); | ||
1377 | printk(KERN_INFO | ||
1378 | "cciss%d: No appropriate SCSI device detected, " | ||
1379 | "SCSI subsystem not engaged.\n", ctlr); | ||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | static int | ||
1384 | cciss_engage_scsi(int ctlr) | 1544 | cciss_engage_scsi(int ctlr) |
1385 | { | 1545 | { |
1386 | struct cciss_scsi_adapter_data_t *sa; | 1546 | struct cciss_scsi_adapter_data_t *sa; |
@@ -1391,15 +1551,15 @@ cciss_engage_scsi(int ctlr) | |||
1391 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; | 1551 | sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr; |
1392 | stk = &sa->cmd_stack; | 1552 | stk = &sa->cmd_stack; |
1393 | 1553 | ||
1394 | if (((struct cciss_scsi_adapter_data_t *) | 1554 | if (sa->registered) { |
1395 | hba[ctlr]->scsi_ctlr)->registered) { | ||
1396 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); | 1555 | printk("cciss%d: SCSI subsystem already engaged.\n", ctlr); |
1397 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1556 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
1398 | return ENXIO; | 1557 | return ENXIO; |
1399 | } | 1558 | } |
1559 | sa->registered = 1; | ||
1400 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); | 1560 | spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags); |
1401 | cciss_update_non_disk_devices(ctlr, -1); | 1561 | cciss_update_non_disk_devices(ctlr, -1); |
1402 | cciss_register_scsi(ctlr); | 1562 | cciss_scsi_detect(ctlr); |
1403 | return 0; | 1563 | return 0; |
1404 | } | 1564 | } |
1405 | 1565 | ||
@@ -1493,7 +1653,5 @@ static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd) | |||
1493 | /* If no tape support, then these become defined out of existence */ | 1653 | /* If no tape support, then these become defined out of existence */ |
1494 | 1654 | ||
1495 | #define cciss_scsi_setup(cntl_num) | 1655 | #define cciss_scsi_setup(cntl_num) |
1496 | #define cciss_unregister_scsi(ctlr) | ||
1497 | #define cciss_register_scsi(ctlr) | ||
1498 | 1656 | ||
1499 | #endif /* CONFIG_CISS_SCSI_TAPE */ | 1657 | #endif /* CONFIG_CISS_SCSI_TAPE */ |
diff --git a/drivers/block/cciss_scsi.h b/drivers/block/cciss_scsi.h index d9c2c586502..7b750245ae7 100644 --- a/drivers/block/cciss_scsi.h +++ b/drivers/block/cciss_scsi.h | |||
@@ -66,6 +66,10 @@ struct cciss_scsi_dev_t { | |||
66 | int devtype; | 66 | int devtype; |
67 | int bus, target, lun; /* as presented to the OS */ | 67 | int bus, target, lun; /* as presented to the OS */ |
68 | unsigned char scsi3addr[8]; /* as presented to the HW */ | 68 | unsigned char scsi3addr[8]; /* as presented to the HW */ |
69 | unsigned char device_id[16]; /* from inquiry pg. 0x83 */ | ||
70 | unsigned char vendor[8]; /* bytes 8-15 of inquiry data */ | ||
71 | unsigned char model[16]; /* bytes 16-31 of inquiry data */ | ||
72 | unsigned char revision[4]; /* bytes 32-35 of inquiry data */ | ||
69 | }; | 73 | }; |
70 | 74 | ||
71 | struct cciss_scsi_hba_t { | 75 | struct cciss_scsi_hba_t { |
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 09c14341e6e..3d967525e9a 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c | |||
@@ -424,7 +424,7 @@ static int __init cpqarray_register_ctlr( int i, struct pci_dev *pdev) | |||
424 | hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), | 424 | hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), |
425 | &(hba[i]->cmd_pool_dhandle)); | 425 | &(hba[i]->cmd_pool_dhandle)); |
426 | hba[i]->cmd_pool_bits = kcalloc( | 426 | hba[i]->cmd_pool_bits = kcalloc( |
427 | (NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG, sizeof(unsigned long), | 427 | DIV_ROUND_UP(NR_CMDS, BITS_PER_LONG), sizeof(unsigned long), |
428 | GFP_KERNEL); | 428 | GFP_KERNEL); |
429 | 429 | ||
430 | if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) | 430 | if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool) |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 395f8ea7981..cf64ddf5d83 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -423,8 +423,15 @@ static struct floppy_raw_cmd *raw_cmd, default_raw_cmd; | |||
423 | * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical | 423 | * 1581's logical side 0 is on physical side 1, whereas the Sharp's logical |
424 | * side 0 is on physical side 0 (but with the misnamed sector IDs). | 424 | * side 0 is on physical side 0 (but with the misnamed sector IDs). |
425 | * 'stretch' should probably be renamed to something more general, like | 425 | * 'stretch' should probably be renamed to something more general, like |
426 | * 'options'. Other parameters should be self-explanatory (see also | 426 | * 'options'. |
427 | * setfdprm(8)). | 427 | * |
428 | * Bits 2 through 9 of 'stretch' tell the number of the first sector. | ||
429 | * The LSB (bit 2) is flipped. For most disks, the first sector | ||
430 | * is 1 (represented by 0x00<<2). For some CP/M and music sampler | ||
431 | * disks (such as Ensoniq EPS 16plus) it is 0 (represented as 0x01<<2). | ||
432 | * For Amstrad CPC disks it is 0xC1 (represented as 0xC0<<2). | ||
433 | * | ||
434 | * Other parameters should be self-explanatory (see also setfdprm(8)). | ||
428 | */ | 435 | */ |
429 | /* | 436 | /* |
430 | Size | 437 | Size |
@@ -1355,20 +1362,20 @@ static void fdc_specify(void) | |||
1355 | } | 1362 | } |
1356 | 1363 | ||
1357 | /* Convert step rate from microseconds to milliseconds and 4 bits */ | 1364 | /* Convert step rate from microseconds to milliseconds and 4 bits */ |
1358 | srt = 16 - (DP->srt * scale_dtr / 1000 + NOMINAL_DTR - 1) / NOMINAL_DTR; | 1365 | srt = 16 - DIV_ROUND_UP(DP->srt * scale_dtr / 1000, NOMINAL_DTR); |
1359 | if (slow_floppy) { | 1366 | if (slow_floppy) { |
1360 | srt = srt / 4; | 1367 | srt = srt / 4; |
1361 | } | 1368 | } |
1362 | SUPBOUND(srt, 0xf); | 1369 | SUPBOUND(srt, 0xf); |
1363 | INFBOUND(srt, 0); | 1370 | INFBOUND(srt, 0); |
1364 | 1371 | ||
1365 | hlt = (DP->hlt * scale_dtr / 2 + NOMINAL_DTR - 1) / NOMINAL_DTR; | 1372 | hlt = DIV_ROUND_UP(DP->hlt * scale_dtr / 2, NOMINAL_DTR); |
1366 | if (hlt < 0x01) | 1373 | if (hlt < 0x01) |
1367 | hlt = 0x01; | 1374 | hlt = 0x01; |
1368 | else if (hlt > 0x7f) | 1375 | else if (hlt > 0x7f) |
1369 | hlt = hlt_max_code; | 1376 | hlt = hlt_max_code; |
1370 | 1377 | ||
1371 | hut = (DP->hut * scale_dtr / 16 + NOMINAL_DTR - 1) / NOMINAL_DTR; | 1378 | hut = DIV_ROUND_UP(DP->hut * scale_dtr / 16, NOMINAL_DTR); |
1372 | if (hut < 0x1) | 1379 | if (hut < 0x1) |
1373 | hut = 0x1; | 1380 | hut = 0x1; |
1374 | else if (hut > 0xf) | 1381 | else if (hut > 0xf) |
@@ -2236,9 +2243,9 @@ static void setup_format_params(int track) | |||
2236 | } | 2243 | } |
2237 | } | 2244 | } |
2238 | } | 2245 | } |
2239 | if (_floppy->stretch & FD_ZEROBASED) { | 2246 | if (_floppy->stretch & FD_SECTBASEMASK) { |
2240 | for (count = 0; count < F_SECT_PER_TRACK; count++) | 2247 | for (count = 0; count < F_SECT_PER_TRACK; count++) |
2241 | here[count].sect--; | 2248 | here[count].sect += FD_SECTBASE(_floppy) - 1; |
2242 | } | 2249 | } |
2243 | } | 2250 | } |
2244 | 2251 | ||
@@ -2385,7 +2392,7 @@ static void rw_interrupt(void) | |||
2385 | 2392 | ||
2386 | #ifdef FLOPPY_SANITY_CHECK | 2393 | #ifdef FLOPPY_SANITY_CHECK |
2387 | if (nr_sectors / ssize > | 2394 | if (nr_sectors / ssize > |
2388 | (in_sector_offset + current_count_sectors + ssize - 1) / ssize) { | 2395 | DIV_ROUND_UP(in_sector_offset + current_count_sectors, ssize)) { |
2389 | DPRINT("long rw: %x instead of %lx\n", | 2396 | DPRINT("long rw: %x instead of %lx\n", |
2390 | nr_sectors, current_count_sectors); | 2397 | nr_sectors, current_count_sectors); |
2391 | printk("rs=%d s=%d\n", R_SECTOR, SECTOR); | 2398 | printk("rs=%d s=%d\n", R_SECTOR, SECTOR); |
@@ -2649,7 +2656,7 @@ static int make_raw_rw_request(void) | |||
2649 | } | 2656 | } |
2650 | HEAD = fsector_t / _floppy->sect; | 2657 | HEAD = fsector_t / _floppy->sect; |
2651 | 2658 | ||
2652 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_ZEROBASED)) || | 2659 | if (((_floppy->stretch & (FD_SWAPSIDES | FD_SECTBASEMASK)) || |
2653 | TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) | 2660 | TESTF(FD_NEED_TWADDLE)) && fsector_t < _floppy->sect) |
2654 | max_sector = _floppy->sect; | 2661 | max_sector = _floppy->sect; |
2655 | 2662 | ||
@@ -2679,7 +2686,7 @@ static int make_raw_rw_request(void) | |||
2679 | CODE2SIZE; | 2686 | CODE2SIZE; |
2680 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; | 2687 | SECT_PER_TRACK = _floppy->sect << 2 >> SIZECODE; |
2681 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + | 2688 | SECTOR = ((fsector_t % _floppy->sect) << 2 >> SIZECODE) + |
2682 | ((_floppy->stretch & FD_ZEROBASED) ? 0 : 1); | 2689 | FD_SECTBASE(_floppy); |
2683 | 2690 | ||
2684 | /* tracksize describes the size which can be filled up with sectors | 2691 | /* tracksize describes the size which can be filled up with sectors |
2685 | * of size ssize. | 2692 | * of size ssize. |
@@ -3311,7 +3318,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3311 | g->head <= 0 || | 3318 | g->head <= 0 || |
3312 | g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) || | 3319 | g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) || |
3313 | /* check if reserved bits are set */ | 3320 | /* check if reserved bits are set */ |
3314 | (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_ZEROBASED)) != 0) | 3321 | (g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0) |
3315 | return -EINVAL; | 3322 | return -EINVAL; |
3316 | if (type) { | 3323 | if (type) { |
3317 | if (!capable(CAP_SYS_ADMIN)) | 3324 | if (!capable(CAP_SYS_ADMIN)) |
@@ -3356,7 +3363,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3356 | if (DRS->maxblock > user_params[drive].sect || | 3363 | if (DRS->maxblock > user_params[drive].sect || |
3357 | DRS->maxtrack || | 3364 | DRS->maxtrack || |
3358 | ((user_params[drive].sect ^ oldStretch) & | 3365 | ((user_params[drive].sect ^ oldStretch) & |
3359 | (FD_SWAPSIDES | FD_ZEROBASED))) | 3366 | (FD_SWAPSIDES | FD_SECTBASEMASK))) |
3360 | invalidate_drive(bdev); | 3367 | invalidate_drive(bdev); |
3361 | else | 3368 | else |
3362 | process_fd_request(); | 3369 | process_fd_request(); |
diff --git a/drivers/block/hd.c b/drivers/block/hd.c new file mode 100644 index 00000000000..482c0c4b964 --- /dev/null +++ b/drivers/block/hd.c | |||
@@ -0,0 +1,815 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * | ||
4 | * This is the low-level hd interrupt support. It traverses the | ||
5 | * request-list, using interrupts to jump between functions. As | ||
6 | * all the functions are called within interrupts, we may not | ||
7 | * sleep. Special care is recommended. | ||
8 | * | ||
9 | * modified by Drew Eckhardt to check nr of hd's from the CMOS. | ||
10 | * | ||
11 | * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug | ||
12 | * in the early extended-partition checks and added DM partitions | ||
13 | * | ||
14 | * IRQ-unmask, drive-id, multiple-mode, support for ">16 heads", | ||
15 | * and general streamlining by Mark Lord. | ||
16 | * | ||
17 | * Removed 99% of above. Use Mark's ide driver for those options. | ||
18 | * This is now a lightweight ST-506 driver. (Paul Gortmaker) | ||
19 | * | ||
20 | * Modified 1995 Russell King for ARM processor. | ||
21 | * | ||
22 | * Bugfix: max_sectors must be <= 255 or the wheels tend to come | ||
23 | * off in a hurry once you queue things up - Paul G. 02/2001 | ||
24 | */ | ||
25 | |||
26 | /* Uncomment the following if you want verbose error reports. */ | ||
27 | /* #define VERBOSE_ERRORS */ | ||
28 | |||
29 | #include <linux/blkdev.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/signal.h> | ||
32 | #include <linux/interrupt.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/kernel.h> | ||
36 | #include <linux/genhd.h> | ||
37 | #include <linux/slab.h> | ||
38 | #include <linux/string.h> | ||
39 | #include <linux/ioport.h> | ||
40 | #include <linux/init.h> | ||
41 | #include <linux/blkpg.h> | ||
42 | #include <linux/ata.h> | ||
43 | #include <linux/hdreg.h> | ||
44 | |||
45 | #define REALLY_SLOW_IO | ||
46 | #include <asm/system.h> | ||
47 | #include <asm/io.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | |||
50 | #ifdef __arm__ | ||
51 | #undef HD_IRQ | ||
52 | #endif | ||
53 | #include <asm/irq.h> | ||
54 | #ifdef __arm__ | ||
55 | #define HD_IRQ IRQ_HARDDISK | ||
56 | #endif | ||
57 | |||
58 | /* Hd controller regster ports */ | ||
59 | |||
60 | #define HD_DATA 0x1f0 /* _CTL when writing */ | ||
61 | #define HD_ERROR 0x1f1 /* see err-bits */ | ||
62 | #define HD_NSECTOR 0x1f2 /* nr of sectors to read/write */ | ||
63 | #define HD_SECTOR 0x1f3 /* starting sector */ | ||
64 | #define HD_LCYL 0x1f4 /* starting cylinder */ | ||
65 | #define HD_HCYL 0x1f5 /* high byte of starting cyl */ | ||
66 | #define HD_CURRENT 0x1f6 /* 101dhhhh , d=drive, hhhh=head */ | ||
67 | #define HD_STATUS 0x1f7 /* see status-bits */ | ||
68 | #define HD_FEATURE HD_ERROR /* same io address, read=error, write=feature */ | ||
69 | #define HD_PRECOMP HD_FEATURE /* obsolete use of this port - predates IDE */ | ||
70 | #define HD_COMMAND HD_STATUS /* same io address, read=status, write=cmd */ | ||
71 | |||
72 | #define HD_CMD 0x3f6 /* used for resets */ | ||
73 | #define HD_ALTSTATUS 0x3f6 /* same as HD_STATUS but doesn't clear irq */ | ||
74 | |||
75 | /* Bits of HD_STATUS */ | ||
76 | #define ERR_STAT 0x01 | ||
77 | #define INDEX_STAT 0x02 | ||
78 | #define ECC_STAT 0x04 /* Corrected error */ | ||
79 | #define DRQ_STAT 0x08 | ||
80 | #define SEEK_STAT 0x10 | ||
81 | #define SERVICE_STAT SEEK_STAT | ||
82 | #define WRERR_STAT 0x20 | ||
83 | #define READY_STAT 0x40 | ||
84 | #define BUSY_STAT 0x80 | ||
85 | |||
86 | /* Bits for HD_ERROR */ | ||
87 | #define MARK_ERR 0x01 /* Bad address mark */ | ||
88 | #define TRK0_ERR 0x02 /* couldn't find track 0 */ | ||
89 | #define ABRT_ERR 0x04 /* Command aborted */ | ||
90 | #define MCR_ERR 0x08 /* media change request */ | ||
91 | #define ID_ERR 0x10 /* ID field not found */ | ||
92 | #define MC_ERR 0x20 /* media changed */ | ||
93 | #define ECC_ERR 0x40 /* Uncorrectable ECC error */ | ||
94 | #define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */ | ||
95 | #define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */ | ||
96 | |||
97 | static DEFINE_SPINLOCK(hd_lock); | ||
98 | static struct request_queue *hd_queue; | ||
99 | |||
100 | #define MAJOR_NR HD_MAJOR | ||
101 | #define QUEUE (hd_queue) | ||
102 | #define CURRENT elv_next_request(hd_queue) | ||
103 | |||
104 | #define TIMEOUT_VALUE (6*HZ) | ||
105 | #define HD_DELAY 0 | ||
106 | |||
107 | #define MAX_ERRORS 16 /* Max read/write errors/sector */ | ||
108 | #define RESET_FREQ 8 /* Reset controller every 8th retry */ | ||
109 | #define RECAL_FREQ 4 /* Recalibrate every 4th retry */ | ||
110 | #define MAX_HD 2 | ||
111 | |||
112 | #define STAT_OK (READY_STAT|SEEK_STAT) | ||
113 | #define OK_STATUS(s) (((s)&(STAT_OK|(BUSY_STAT|WRERR_STAT|ERR_STAT)))==STAT_OK) | ||
114 | |||
115 | static void recal_intr(void); | ||
116 | static void bad_rw_intr(void); | ||
117 | |||
118 | static int reset; | ||
119 | static int hd_error; | ||
120 | |||
121 | /* | ||
122 | * This struct defines the HD's and their types. | ||
123 | */ | ||
124 | struct hd_i_struct { | ||
125 | unsigned int head, sect, cyl, wpcom, lzone, ctl; | ||
126 | int unit; | ||
127 | int recalibrate; | ||
128 | int special_op; | ||
129 | }; | ||
130 | |||
131 | #ifdef HD_TYPE | ||
132 | static struct hd_i_struct hd_info[] = { HD_TYPE }; | ||
133 | static int NR_HD = ARRAY_SIZE(hd_info); | ||
134 | #else | ||
135 | static struct hd_i_struct hd_info[MAX_HD]; | ||
136 | static int NR_HD; | ||
137 | #endif | ||
138 | |||
139 | static struct gendisk *hd_gendisk[MAX_HD]; | ||
140 | |||
141 | static struct timer_list device_timer; | ||
142 | |||
143 | #define TIMEOUT_VALUE (6*HZ) | ||
144 | |||
145 | #define SET_TIMER \ | ||
146 | do { \ | ||
147 | mod_timer(&device_timer, jiffies + TIMEOUT_VALUE); \ | ||
148 | } while (0) | ||
149 | |||
150 | static void (*do_hd)(void) = NULL; | ||
151 | #define SET_HANDLER(x) \ | ||
152 | if ((do_hd = (x)) != NULL) \ | ||
153 | SET_TIMER; \ | ||
154 | else \ | ||
155 | del_timer(&device_timer); | ||
156 | |||
157 | |||
158 | #if (HD_DELAY > 0) | ||
159 | |||
160 | #include <asm/i8253.h> | ||
161 | |||
162 | unsigned long last_req; | ||
163 | |||
164 | unsigned long read_timer(void) | ||
165 | { | ||
166 | unsigned long t, flags; | ||
167 | int i; | ||
168 | |||
169 | spin_lock_irqsave(&i8253_lock, flags); | ||
170 | t = jiffies * 11932; | ||
171 | outb_p(0, 0x43); | ||
172 | i = inb_p(0x40); | ||
173 | i |= inb(0x40) << 8; | ||
174 | spin_unlock_irqrestore(&i8253_lock, flags); | ||
175 | return(t - i); | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | static void __init hd_setup(char *str, int *ints) | ||
180 | { | ||
181 | int hdind = 0; | ||
182 | |||
183 | if (ints[0] != 3) | ||
184 | return; | ||
185 | if (hd_info[0].head != 0) | ||
186 | hdind = 1; | ||
187 | hd_info[hdind].head = ints[2]; | ||
188 | hd_info[hdind].sect = ints[3]; | ||
189 | hd_info[hdind].cyl = ints[1]; | ||
190 | hd_info[hdind].wpcom = 0; | ||
191 | hd_info[hdind].lzone = ints[1]; | ||
192 | hd_info[hdind].ctl = (ints[2] > 8 ? 8 : 0); | ||
193 | NR_HD = hdind+1; | ||
194 | } | ||
195 | |||
196 | static void dump_status(const char *msg, unsigned int stat) | ||
197 | { | ||
198 | char *name = "hd?"; | ||
199 | if (CURRENT) | ||
200 | name = CURRENT->rq_disk->disk_name; | ||
201 | |||
202 | #ifdef VERBOSE_ERRORS | ||
203 | printk("%s: %s: status=0x%02x { ", name, msg, stat & 0xff); | ||
204 | if (stat & BUSY_STAT) printk("Busy "); | ||
205 | if (stat & READY_STAT) printk("DriveReady "); | ||
206 | if (stat & WRERR_STAT) printk("WriteFault "); | ||
207 | if (stat & SEEK_STAT) printk("SeekComplete "); | ||
208 | if (stat & DRQ_STAT) printk("DataRequest "); | ||
209 | if (stat & ECC_STAT) printk("CorrectedError "); | ||
210 | if (stat & INDEX_STAT) printk("Index "); | ||
211 | if (stat & ERR_STAT) printk("Error "); | ||
212 | printk("}\n"); | ||
213 | if ((stat & ERR_STAT) == 0) { | ||
214 | hd_error = 0; | ||
215 | } else { | ||
216 | hd_error = inb(HD_ERROR); | ||
217 | printk("%s: %s: error=0x%02x { ", name, msg, hd_error & 0xff); | ||
218 | if (hd_error & BBD_ERR) printk("BadSector "); | ||
219 | if (hd_error & ECC_ERR) printk("UncorrectableError "); | ||
220 | if (hd_error & ID_ERR) printk("SectorIdNotFound "); | ||
221 | if (hd_error & ABRT_ERR) printk("DriveStatusError "); | ||
222 | if (hd_error & TRK0_ERR) printk("TrackZeroNotFound "); | ||
223 | if (hd_error & MARK_ERR) printk("AddrMarkNotFound "); | ||
224 | printk("}"); | ||
225 | if (hd_error & (BBD_ERR|ECC_ERR|ID_ERR|MARK_ERR)) { | ||
226 | printk(", CHS=%d/%d/%d", (inb(HD_HCYL)<<8) + inb(HD_LCYL), | ||
227 | inb(HD_CURRENT) & 0xf, inb(HD_SECTOR)); | ||
228 | if (CURRENT) | ||
229 | printk(", sector=%ld", CURRENT->sector); | ||
230 | } | ||
231 | printk("\n"); | ||
232 | } | ||
233 | #else | ||
234 | printk("%s: %s: status=0x%02x.\n", name, msg, stat & 0xff); | ||
235 | if ((stat & ERR_STAT) == 0) { | ||
236 | hd_error = 0; | ||
237 | } else { | ||
238 | hd_error = inb(HD_ERROR); | ||
239 | printk("%s: %s: error=0x%02x.\n", name, msg, hd_error & 0xff); | ||
240 | } | ||
241 | #endif | ||
242 | } | ||
243 | |||
244 | static void check_status(void) | ||
245 | { | ||
246 | int i = inb_p(HD_STATUS); | ||
247 | |||
248 | if (!OK_STATUS(i)) { | ||
249 | dump_status("check_status", i); | ||
250 | bad_rw_intr(); | ||
251 | } | ||
252 | } | ||
253 | |||
254 | static int controller_busy(void) | ||
255 | { | ||
256 | int retries = 100000; | ||
257 | unsigned char status; | ||
258 | |||
259 | do { | ||
260 | status = inb_p(HD_STATUS); | ||
261 | } while ((status & BUSY_STAT) && --retries); | ||
262 | return status; | ||
263 | } | ||
264 | |||
265 | static int status_ok(void) | ||
266 | { | ||
267 | unsigned char status = inb_p(HD_STATUS); | ||
268 | |||
269 | if (status & BUSY_STAT) | ||
270 | return 1; /* Ancient, but does it make sense??? */ | ||
271 | if (status & WRERR_STAT) | ||
272 | return 0; | ||
273 | if (!(status & READY_STAT)) | ||
274 | return 0; | ||
275 | if (!(status & SEEK_STAT)) | ||
276 | return 0; | ||
277 | return 1; | ||
278 | } | ||
279 | |||
280 | static int controller_ready(unsigned int drive, unsigned int head) | ||
281 | { | ||
282 | int retry = 100; | ||
283 | |||
284 | do { | ||
285 | if (controller_busy() & BUSY_STAT) | ||
286 | return 0; | ||
287 | outb_p(0xA0 | (drive<<4) | head, HD_CURRENT); | ||
288 | if (status_ok()) | ||
289 | return 1; | ||
290 | } while (--retry); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void hd_out(struct hd_i_struct *disk, | ||
295 | unsigned int nsect, | ||
296 | unsigned int sect, | ||
297 | unsigned int head, | ||
298 | unsigned int cyl, | ||
299 | unsigned int cmd, | ||
300 | void (*intr_addr)(void)) | ||
301 | { | ||
302 | unsigned short port; | ||
303 | |||
304 | #if (HD_DELAY > 0) | ||
305 | while (read_timer() - last_req < HD_DELAY) | ||
306 | /* nothing */; | ||
307 | #endif | ||
308 | if (reset) | ||
309 | return; | ||
310 | if (!controller_ready(disk->unit, head)) { | ||
311 | reset = 1; | ||
312 | return; | ||
313 | } | ||
314 | SET_HANDLER(intr_addr); | ||
315 | outb_p(disk->ctl, HD_CMD); | ||
316 | port = HD_DATA; | ||
317 | outb_p(disk->wpcom >> 2, ++port); | ||
318 | outb_p(nsect, ++port); | ||
319 | outb_p(sect, ++port); | ||
320 | outb_p(cyl, ++port); | ||
321 | outb_p(cyl >> 8, ++port); | ||
322 | outb_p(0xA0 | (disk->unit << 4) | head, ++port); | ||
323 | outb_p(cmd, ++port); | ||
324 | } | ||
325 | |||
326 | static void hd_request (void); | ||
327 | |||
328 | static int drive_busy(void) | ||
329 | { | ||
330 | unsigned int i; | ||
331 | unsigned char c; | ||
332 | |||
333 | for (i = 0; i < 500000 ; i++) { | ||
334 | c = inb_p(HD_STATUS); | ||
335 | if ((c & (BUSY_STAT | READY_STAT | SEEK_STAT)) == STAT_OK) | ||
336 | return 0; | ||
337 | } | ||
338 | dump_status("reset timed out", c); | ||
339 | return 1; | ||
340 | } | ||
341 | |||
342 | static void reset_controller(void) | ||
343 | { | ||
344 | int i; | ||
345 | |||
346 | outb_p(4, HD_CMD); | ||
347 | for (i = 0; i < 1000; i++) barrier(); | ||
348 | outb_p(hd_info[0].ctl & 0x0f, HD_CMD); | ||
349 | for (i = 0; i < 1000; i++) barrier(); | ||
350 | if (drive_busy()) | ||
351 | printk("hd: controller still busy\n"); | ||
352 | else if ((hd_error = inb(HD_ERROR)) != 1) | ||
353 | printk("hd: controller reset failed: %02x\n", hd_error); | ||
354 | } | ||
355 | |||
356 | static void reset_hd(void) | ||
357 | { | ||
358 | static int i; | ||
359 | |||
360 | repeat: | ||
361 | if (reset) { | ||
362 | reset = 0; | ||
363 | i = -1; | ||
364 | reset_controller(); | ||
365 | } else { | ||
366 | check_status(); | ||
367 | if (reset) | ||
368 | goto repeat; | ||
369 | } | ||
370 | if (++i < NR_HD) { | ||
371 | struct hd_i_struct *disk = &hd_info[i]; | ||
372 | disk->special_op = disk->recalibrate = 1; | ||
373 | hd_out(disk, disk->sect, disk->sect, disk->head-1, | ||
374 | disk->cyl, ATA_CMD_INIT_DEV_PARAMS, &reset_hd); | ||
375 | if (reset) | ||
376 | goto repeat; | ||
377 | } else | ||
378 | hd_request(); | ||
379 | } | ||
380 | |||
381 | /* | ||
382 | * Ok, don't know what to do with the unexpected interrupts: on some machines | ||
383 | * doing a reset and a retry seems to result in an eternal loop. Right now I | ||
384 | * ignore it, and just set the timeout. | ||
385 | * | ||
386 | * On laptops (and "green" PCs), an unexpected interrupt occurs whenever the | ||
387 | * drive enters "idle", "standby", or "sleep" mode, so if the status looks | ||
388 | * "good", we just ignore the interrupt completely. | ||
389 | */ | ||
390 | static void unexpected_hd_interrupt(void) | ||
391 | { | ||
392 | unsigned int stat = inb_p(HD_STATUS); | ||
393 | |||
394 | if (stat & (BUSY_STAT|DRQ_STAT|ECC_STAT|ERR_STAT)) { | ||
395 | dump_status("unexpected interrupt", stat); | ||
396 | SET_TIMER; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | /* | ||
401 | * bad_rw_intr() now tries to be a bit smarter and does things | ||
402 | * according to the error returned by the controller. | ||
403 | * -Mika Liljeberg (liljeber@cs.Helsinki.FI) | ||
404 | */ | ||
405 | static void bad_rw_intr(void) | ||
406 | { | ||
407 | struct request *req = CURRENT; | ||
408 | if (req != NULL) { | ||
409 | struct hd_i_struct *disk = req->rq_disk->private_data; | ||
410 | if (++req->errors >= MAX_ERRORS || (hd_error & BBD_ERR)) { | ||
411 | end_request(req, 0); | ||
412 | disk->special_op = disk->recalibrate = 1; | ||
413 | } else if (req->errors % RESET_FREQ == 0) | ||
414 | reset = 1; | ||
415 | else if ((hd_error & TRK0_ERR) || req->errors % RECAL_FREQ == 0) | ||
416 | disk->special_op = disk->recalibrate = 1; | ||
417 | /* Otherwise just retry */ | ||
418 | } | ||
419 | } | ||
420 | |||
421 | static inline int wait_DRQ(void) | ||
422 | { | ||
423 | int retries; | ||
424 | int stat; | ||
425 | |||
426 | for (retries = 0; retries < 100000; retries++) { | ||
427 | stat = inb_p(HD_STATUS); | ||
428 | if (stat & DRQ_STAT) | ||
429 | return 0; | ||
430 | } | ||
431 | dump_status("wait_DRQ", stat); | ||
432 | return -1; | ||
433 | } | ||
434 | |||
435 | static void read_intr(void) | ||
436 | { | ||
437 | struct request *req; | ||
438 | int i, retries = 100000; | ||
439 | |||
440 | do { | ||
441 | i = (unsigned) inb_p(HD_STATUS); | ||
442 | if (i & BUSY_STAT) | ||
443 | continue; | ||
444 | if (!OK_STATUS(i)) | ||
445 | break; | ||
446 | if (i & DRQ_STAT) | ||
447 | goto ok_to_read; | ||
448 | } while (--retries > 0); | ||
449 | dump_status("read_intr", i); | ||
450 | bad_rw_intr(); | ||
451 | hd_request(); | ||
452 | return; | ||
453 | ok_to_read: | ||
454 | req = CURRENT; | ||
455 | insw(HD_DATA, req->buffer, 256); | ||
456 | req->sector++; | ||
457 | req->buffer += 512; | ||
458 | req->errors = 0; | ||
459 | i = --req->nr_sectors; | ||
460 | --req->current_nr_sectors; | ||
461 | #ifdef DEBUG | ||
462 | printk("%s: read: sector %ld, remaining = %ld, buffer=%p\n", | ||
463 | req->rq_disk->disk_name, req->sector, req->nr_sectors, | ||
464 | req->buffer+512); | ||
465 | #endif | ||
466 | if (req->current_nr_sectors <= 0) | ||
467 | end_request(req, 1); | ||
468 | if (i > 0) { | ||
469 | SET_HANDLER(&read_intr); | ||
470 | return; | ||
471 | } | ||
472 | (void) inb_p(HD_STATUS); | ||
473 | #if (HD_DELAY > 0) | ||
474 | last_req = read_timer(); | ||
475 | #endif | ||
476 | if (elv_next_request(QUEUE)) | ||
477 | hd_request(); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | static void write_intr(void) | ||
482 | { | ||
483 | struct request *req = CURRENT; | ||
484 | int i; | ||
485 | int retries = 100000; | ||
486 | |||
487 | do { | ||
488 | i = (unsigned) inb_p(HD_STATUS); | ||
489 | if (i & BUSY_STAT) | ||
490 | continue; | ||
491 | if (!OK_STATUS(i)) | ||
492 | break; | ||
493 | if ((req->nr_sectors <= 1) || (i & DRQ_STAT)) | ||
494 | goto ok_to_write; | ||
495 | } while (--retries > 0); | ||
496 | dump_status("write_intr", i); | ||
497 | bad_rw_intr(); | ||
498 | hd_request(); | ||
499 | return; | ||
500 | ok_to_write: | ||
501 | req->sector++; | ||
502 | i = --req->nr_sectors; | ||
503 | --req->current_nr_sectors; | ||
504 | req->buffer += 512; | ||
505 | if (!i || (req->bio && req->current_nr_sectors <= 0)) | ||
506 | end_request(req, 1); | ||
507 | if (i > 0) { | ||
508 | SET_HANDLER(&write_intr); | ||
509 | outsw(HD_DATA, req->buffer, 256); | ||
510 | local_irq_enable(); | ||
511 | } else { | ||
512 | #if (HD_DELAY > 0) | ||
513 | last_req = read_timer(); | ||
514 | #endif | ||
515 | hd_request(); | ||
516 | } | ||
517 | return; | ||
518 | } | ||
519 | |||
520 | static void recal_intr(void) | ||
521 | { | ||
522 | check_status(); | ||
523 | #if (HD_DELAY > 0) | ||
524 | last_req = read_timer(); | ||
525 | #endif | ||
526 | hd_request(); | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * This is another of the error-routines I don't know what to do with. The | ||
531 | * best idea seems to just set reset, and start all over again. | ||
532 | */ | ||
533 | static void hd_times_out(unsigned long dummy) | ||
534 | { | ||
535 | char *name; | ||
536 | |||
537 | do_hd = NULL; | ||
538 | |||
539 | if (!CURRENT) | ||
540 | return; | ||
541 | |||
542 | disable_irq(HD_IRQ); | ||
543 | local_irq_enable(); | ||
544 | reset = 1; | ||
545 | name = CURRENT->rq_disk->disk_name; | ||
546 | printk("%s: timeout\n", name); | ||
547 | if (++CURRENT->errors >= MAX_ERRORS) { | ||
548 | #ifdef DEBUG | ||
549 | printk("%s: too many errors\n", name); | ||
550 | #endif | ||
551 | end_request(CURRENT, 0); | ||
552 | } | ||
553 | local_irq_disable(); | ||
554 | hd_request(); | ||
555 | enable_irq(HD_IRQ); | ||
556 | } | ||
557 | |||
558 | static int do_special_op(struct hd_i_struct *disk, struct request *req) | ||
559 | { | ||
560 | if (disk->recalibrate) { | ||
561 | disk->recalibrate = 0; | ||
562 | hd_out(disk, disk->sect, 0, 0, 0, ATA_CMD_RESTORE, &recal_intr); | ||
563 | return reset; | ||
564 | } | ||
565 | if (disk->head > 16) { | ||
566 | printk("%s: cannot handle device with more than 16 heads - giving up\n", req->rq_disk->disk_name); | ||
567 | end_request(req, 0); | ||
568 | } | ||
569 | disk->special_op = 0; | ||
570 | return 1; | ||
571 | } | ||
572 | |||
573 | /* | ||
574 | * The driver enables interrupts as much as possible. In order to do this, | ||
575 | * (a) the device-interrupt is disabled before entering hd_request(), | ||
576 | * and (b) the timeout-interrupt is disabled before the sti(). | ||
577 | * | ||
578 | * Interrupts are still masked (by default) whenever we are exchanging | ||
579 | * data/cmds with a drive, because some drives seem to have very poor | ||
580 | * tolerance for latency during I/O. The IDE driver has support to unmask | ||
581 | * interrupts for non-broken hardware, so use that driver if required. | ||
582 | */ | ||
583 | static void hd_request(void) | ||
584 | { | ||
585 | unsigned int block, nsect, sec, track, head, cyl; | ||
586 | struct hd_i_struct *disk; | ||
587 | struct request *req; | ||
588 | |||
589 | if (do_hd) | ||
590 | return; | ||
591 | repeat: | ||
592 | del_timer(&device_timer); | ||
593 | local_irq_enable(); | ||
594 | |||
595 | req = CURRENT; | ||
596 | if (!req) { | ||
597 | do_hd = NULL; | ||
598 | return; | ||
599 | } | ||
600 | |||
601 | if (reset) { | ||
602 | local_irq_disable(); | ||
603 | reset_hd(); | ||
604 | return; | ||
605 | } | ||
606 | disk = req->rq_disk->private_data; | ||
607 | block = req->sector; | ||
608 | nsect = req->nr_sectors; | ||
609 | if (block >= get_capacity(req->rq_disk) || | ||
610 | ((block+nsect) > get_capacity(req->rq_disk))) { | ||
611 | printk("%s: bad access: block=%d, count=%d\n", | ||
612 | req->rq_disk->disk_name, block, nsect); | ||
613 | end_request(req, 0); | ||
614 | goto repeat; | ||
615 | } | ||
616 | |||
617 | if (disk->special_op) { | ||
618 | if (do_special_op(disk, req)) | ||
619 | goto repeat; | ||
620 | return; | ||
621 | } | ||
622 | sec = block % disk->sect + 1; | ||
623 | track = block / disk->sect; | ||
624 | head = track % disk->head; | ||
625 | cyl = track / disk->head; | ||
626 | #ifdef DEBUG | ||
627 | printk("%s: %sing: CHS=%d/%d/%d, sectors=%d, buffer=%p\n", | ||
628 | req->rq_disk->disk_name, | ||
629 | req_data_dir(req) == READ ? "read" : "writ", | ||
630 | cyl, head, sec, nsect, req->buffer); | ||
631 | #endif | ||
632 | if (blk_fs_request(req)) { | ||
633 | switch (rq_data_dir(req)) { | ||
634 | case READ: | ||
635 | hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_READ, | ||
636 | &read_intr); | ||
637 | if (reset) | ||
638 | goto repeat; | ||
639 | break; | ||
640 | case WRITE: | ||
641 | hd_out(disk, nsect, sec, head, cyl, ATA_CMD_PIO_WRITE, | ||
642 | &write_intr); | ||
643 | if (reset) | ||
644 | goto repeat; | ||
645 | if (wait_DRQ()) { | ||
646 | bad_rw_intr(); | ||
647 | goto repeat; | ||
648 | } | ||
649 | outsw(HD_DATA, req->buffer, 256); | ||
650 | break; | ||
651 | default: | ||
652 | printk("unknown hd-command\n"); | ||
653 | end_request(req, 0); | ||
654 | break; | ||
655 | } | ||
656 | } | ||
657 | } | ||
658 | |||
659 | static void do_hd_request(struct request_queue *q) | ||
660 | { | ||
661 | disable_irq(HD_IRQ); | ||
662 | hd_request(); | ||
663 | enable_irq(HD_IRQ); | ||
664 | } | ||
665 | |||
666 | static int hd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | ||
667 | { | ||
668 | struct hd_i_struct *disk = bdev->bd_disk->private_data; | ||
669 | |||
670 | geo->heads = disk->head; | ||
671 | geo->sectors = disk->sect; | ||
672 | geo->cylinders = disk->cyl; | ||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | /* | ||
677 | * Releasing a block device means we sync() it, so that it can safely | ||
678 | * be forgotten about... | ||
679 | */ | ||
680 | |||
681 | static irqreturn_t hd_interrupt(int irq, void *dev_id) | ||
682 | { | ||
683 | void (*handler)(void) = do_hd; | ||
684 | |||
685 | do_hd = NULL; | ||
686 | del_timer(&device_timer); | ||
687 | if (!handler) | ||
688 | handler = unexpected_hd_interrupt; | ||
689 | handler(); | ||
690 | local_irq_enable(); | ||
691 | return IRQ_HANDLED; | ||
692 | } | ||
693 | |||
694 | static struct block_device_operations hd_fops = { | ||
695 | .getgeo = hd_getgeo, | ||
696 | }; | ||
697 | |||
698 | /* | ||
699 | * This is the hard disk IRQ description. The IRQF_DISABLED in sa_flags | ||
700 | * means we run the IRQ-handler with interrupts disabled: this is bad for | ||
701 | * interrupt latency, but anything else has led to problems on some | ||
702 | * machines. | ||
703 | * | ||
704 | * We enable interrupts in some of the routines after making sure it's | ||
705 | * safe. | ||
706 | */ | ||
707 | |||
708 | static int __init hd_init(void) | ||
709 | { | ||
710 | int drive; | ||
711 | |||
712 | if (register_blkdev(MAJOR_NR, "hd")) | ||
713 | return -1; | ||
714 | |||
715 | hd_queue = blk_init_queue(do_hd_request, &hd_lock); | ||
716 | if (!hd_queue) { | ||
717 | unregister_blkdev(MAJOR_NR, "hd"); | ||
718 | return -ENOMEM; | ||
719 | } | ||
720 | |||
721 | blk_queue_max_sectors(hd_queue, 255); | ||
722 | init_timer(&device_timer); | ||
723 | device_timer.function = hd_times_out; | ||
724 | blk_queue_hardsect_size(hd_queue, 512); | ||
725 | |||
726 | if (!NR_HD) { | ||
727 | /* | ||
728 | * We don't know anything about the drive. This means | ||
729 | * that you *MUST* specify the drive parameters to the | ||
730 | * kernel yourself. | ||
731 | * | ||
732 | * If we were on an i386, we used to read this info from | ||
733 | * the BIOS or CMOS. This doesn't work all that well, | ||
734 | * since this assumes that this is a primary or secondary | ||
735 | * drive, and if we're using this legacy driver, it's | ||
736 | * probably an auxilliary controller added to recover | ||
737 | * legacy data off an ST-506 drive. Either way, it's | ||
738 | * definitely safest to have the user explicitly specify | ||
739 | * the information. | ||
740 | */ | ||
741 | printk("hd: no drives specified - use hd=cyl,head,sectors" | ||
742 | " on kernel command line\n"); | ||
743 | goto out; | ||
744 | } | ||
745 | |||
746 | for (drive = 0 ; drive < NR_HD ; drive++) { | ||
747 | struct gendisk *disk = alloc_disk(64); | ||
748 | struct hd_i_struct *p = &hd_info[drive]; | ||
749 | if (!disk) | ||
750 | goto Enomem; | ||
751 | disk->major = MAJOR_NR; | ||
752 | disk->first_minor = drive << 6; | ||
753 | disk->fops = &hd_fops; | ||
754 | sprintf(disk->disk_name, "hd%c", 'a'+drive); | ||
755 | disk->private_data = p; | ||
756 | set_capacity(disk, p->head * p->sect * p->cyl); | ||
757 | disk->queue = hd_queue; | ||
758 | p->unit = drive; | ||
759 | hd_gendisk[drive] = disk; | ||
760 | printk("%s: %luMB, CHS=%d/%d/%d\n", | ||
761 | disk->disk_name, (unsigned long)get_capacity(disk)/2048, | ||
762 | p->cyl, p->head, p->sect); | ||
763 | } | ||
764 | |||
765 | if (request_irq(HD_IRQ, hd_interrupt, IRQF_DISABLED, "hd", NULL)) { | ||
766 | printk("hd: unable to get IRQ%d for the hard disk driver\n", | ||
767 | HD_IRQ); | ||
768 | goto out1; | ||
769 | } | ||
770 | if (!request_region(HD_DATA, 8, "hd")) { | ||
771 | printk(KERN_WARNING "hd: port 0x%x busy\n", HD_DATA); | ||
772 | goto out2; | ||
773 | } | ||
774 | if (!request_region(HD_CMD, 1, "hd(cmd)")) { | ||
775 | printk(KERN_WARNING "hd: port 0x%x busy\n", HD_CMD); | ||
776 | goto out3; | ||
777 | } | ||
778 | |||
779 | /* Let them fly */ | ||
780 | for (drive = 0; drive < NR_HD; drive++) | ||
781 | add_disk(hd_gendisk[drive]); | ||
782 | |||
783 | return 0; | ||
784 | |||
785 | out3: | ||
786 | release_region(HD_DATA, 8); | ||
787 | out2: | ||
788 | free_irq(HD_IRQ, NULL); | ||
789 | out1: | ||
790 | for (drive = 0; drive < NR_HD; drive++) | ||
791 | put_disk(hd_gendisk[drive]); | ||
792 | NR_HD = 0; | ||
793 | out: | ||
794 | del_timer(&device_timer); | ||
795 | unregister_blkdev(MAJOR_NR, "hd"); | ||
796 | blk_cleanup_queue(hd_queue); | ||
797 | return -1; | ||
798 | Enomem: | ||
799 | while (drive--) | ||
800 | put_disk(hd_gendisk[drive]); | ||
801 | goto out; | ||
802 | } | ||
803 | |||
804 | static int __init parse_hd_setup(char *line) | ||
805 | { | ||
806 | int ints[6]; | ||
807 | |||
808 | (void) get_options(line, ARRAY_SIZE(ints), ints); | ||
809 | hd_setup(NULL, ints); | ||
810 | |||
811 | return 1; | ||
812 | } | ||
813 | __setup("hd=", parse_hd_setup); | ||
814 | |||
815 | late_initcall(hd_init); | ||
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index ad98dda6037..7b3351260d5 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c | |||
@@ -403,7 +403,7 @@ static int nbd_do_it(struct nbd_device *lo) | |||
403 | BUG_ON(lo->magic != LO_MAGIC); | 403 | BUG_ON(lo->magic != LO_MAGIC); |
404 | 404 | ||
405 | lo->pid = current->pid; | 405 | lo->pid = current->pid; |
406 | ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr); | 406 | ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); |
407 | if (ret) { | 407 | if (ret) { |
408 | printk(KERN_ERR "nbd: sysfs_create_file failed!"); | 408 | printk(KERN_ERR "nbd: sysfs_create_file failed!"); |
409 | return ret; | 409 | return ret; |
@@ -412,7 +412,7 @@ static int nbd_do_it(struct nbd_device *lo) | |||
412 | while ((req = nbd_read_stat(lo)) != NULL) | 412 | while ((req = nbd_read_stat(lo)) != NULL) |
413 | nbd_end_request(req); | 413 | nbd_end_request(req); |
414 | 414 | ||
415 | sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr); | 415 | sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr); |
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | 418 | ||
@@ -707,15 +707,15 @@ static int __init nbd_init(void) | |||
707 | 707 | ||
708 | BUILD_BUG_ON(sizeof(struct nbd_request) != 28); | 708 | BUILD_BUG_ON(sizeof(struct nbd_request) != 28); |
709 | 709 | ||
710 | nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); | ||
711 | if (!nbd_dev) | ||
712 | return -ENOMEM; | ||
713 | |||
714 | if (max_part < 0) { | 710 | if (max_part < 0) { |
715 | printk(KERN_CRIT "nbd: max_part must be >= 0\n"); | 711 | printk(KERN_CRIT "nbd: max_part must be >= 0\n"); |
716 | return -EINVAL; | 712 | return -EINVAL; |
717 | } | 713 | } |
718 | 714 | ||
715 | nbd_dev = kcalloc(nbds_max, sizeof(*nbd_dev), GFP_KERNEL); | ||
716 | if (!nbd_dev) | ||
717 | return -ENOMEM; | ||
718 | |||
719 | part_shift = 0; | 719 | part_shift = 0; |
720 | if (max_part > 0) | 720 | if (max_part > 0) |
721 | part_shift = fls(max_part); | 721 | part_shift = fls(max_part); |
@@ -779,6 +779,7 @@ out: | |||
779 | blk_cleanup_queue(nbd_dev[i].disk->queue); | 779 | blk_cleanup_queue(nbd_dev[i].disk->queue); |
780 | put_disk(nbd_dev[i].disk); | 780 | put_disk(nbd_dev[i].disk); |
781 | } | 781 | } |
782 | kfree(nbd_dev); | ||
782 | return err; | 783 | return err; |
783 | } | 784 | } |
784 | 785 | ||
@@ -795,6 +796,7 @@ static void __exit nbd_cleanup(void) | |||
795 | } | 796 | } |
796 | } | 797 | } |
797 | unregister_blkdev(NBD_MAJOR, "nbd"); | 798 | unregister_blkdev(NBD_MAJOR, "nbd"); |
799 | kfree(nbd_dev); | ||
798 | printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR); | 800 | printk(KERN_INFO "nbd: unregistered device at major %d\n", NBD_MAJOR); |
799 | } | 801 | } |
800 | 802 | ||
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 570f3b70dce..5fdfa7c888c 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c | |||
@@ -712,19 +712,17 @@ static void do_pd_request(struct request_queue * q) | |||
712 | static int pd_special_command(struct pd_unit *disk, | 712 | static int pd_special_command(struct pd_unit *disk, |
713 | enum action (*func)(struct pd_unit *disk)) | 713 | enum action (*func)(struct pd_unit *disk)) |
714 | { | 714 | { |
715 | DECLARE_COMPLETION_ONSTACK(wait); | 715 | struct request *rq; |
716 | struct request rq; | ||
717 | int err = 0; | 716 | int err = 0; |
718 | 717 | ||
719 | blk_rq_init(NULL, &rq); | 718 | rq = blk_get_request(disk->gd->queue, READ, __GFP_WAIT); |
720 | rq.rq_disk = disk->gd; | 719 | |
721 | rq.end_io_data = &wait; | 720 | rq->cmd_type = REQ_TYPE_SPECIAL; |
722 | rq.end_io = blk_end_sync_rq; | 721 | rq->special = func; |
723 | blk_insert_request(disk->gd->queue, &rq, 0, func); | 722 | |
724 | wait_for_completion(&wait); | 723 | err = blk_execute_rq(disk->gd->queue, disk->gd, rq, 0); |
725 | if (rq.errors) | 724 | |
726 | err = -EIO; | 725 | blk_put_request(rq); |
727 | blk_put_request(&rq); | ||
728 | return err; | 726 | return err; |
729 | } | 727 | } |
730 | 728 | ||
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c index ab86e23ddc6..d731ca42f80 100644 --- a/drivers/block/paride/pg.c +++ b/drivers/block/paride/pg.c | |||
@@ -162,6 +162,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY}; | |||
162 | #include <linux/pg.h> | 162 | #include <linux/pg.h> |
163 | #include <linux/device.h> | 163 | #include <linux/device.h> |
164 | #include <linux/sched.h> /* current, TASK_* */ | 164 | #include <linux/sched.h> /* current, TASK_* */ |
165 | #include <linux/smp_lock.h> | ||
165 | #include <linux/jiffies.h> | 166 | #include <linux/jiffies.h> |
166 | 167 | ||
167 | #include <asm/uaccess.h> | 168 | #include <asm/uaccess.h> |
@@ -515,12 +516,18 @@ static int pg_open(struct inode *inode, struct file *file) | |||
515 | { | 516 | { |
516 | int unit = iminor(inode) & 0x7f; | 517 | int unit = iminor(inode) & 0x7f; |
517 | struct pg *dev = &devices[unit]; | 518 | struct pg *dev = &devices[unit]; |
519 | int ret = 0; | ||
518 | 520 | ||
519 | if ((unit >= PG_UNITS) || (!dev->present)) | 521 | lock_kernel(); |
520 | return -ENODEV; | 522 | if ((unit >= PG_UNITS) || (!dev->present)) { |
523 | ret = -ENODEV; | ||
524 | goto out; | ||
525 | } | ||
521 | 526 | ||
522 | if (test_and_set_bit(0, &dev->access)) | 527 | if (test_and_set_bit(0, &dev->access)) { |
523 | return -EBUSY; | 528 | ret = -EBUSY; |
529 | goto out; | ||
530 | } | ||
524 | 531 | ||
525 | if (dev->busy) { | 532 | if (dev->busy) { |
526 | pg_reset(dev); | 533 | pg_reset(dev); |
@@ -533,12 +540,15 @@ static int pg_open(struct inode *inode, struct file *file) | |||
533 | if (dev->bufptr == NULL) { | 540 | if (dev->bufptr == NULL) { |
534 | clear_bit(0, &dev->access); | 541 | clear_bit(0, &dev->access); |
535 | printk("%s: buffer allocation failed\n", dev->name); | 542 | printk("%s: buffer allocation failed\n", dev->name); |
536 | return -ENOMEM; | 543 | ret = -ENOMEM; |
544 | goto out; | ||
537 | } | 545 | } |
538 | 546 | ||
539 | file->private_data = dev; | 547 | file->private_data = dev; |
540 | 548 | ||
541 | return 0; | 549 | out: |
550 | unlock_kernel(); | ||
551 | return ret; | ||
542 | } | 552 | } |
543 | 553 | ||
544 | static int pg_release(struct inode *inode, struct file *file) | 554 | static int pg_release(struct inode *inode, struct file *file) |
@@ -676,8 +686,9 @@ static int __init pg_init(void) | |||
676 | for (unit = 0; unit < PG_UNITS; unit++) { | 686 | for (unit = 0; unit < PG_UNITS; unit++) { |
677 | struct pg *dev = &devices[unit]; | 687 | struct pg *dev = &devices[unit]; |
678 | if (dev->present) | 688 | if (dev->present) |
679 | device_create(pg_class, NULL, MKDEV(major, unit), | 689 | device_create_drvdata(pg_class, NULL, |
680 | "pg%u", unit); | 690 | MKDEV(major, unit), NULL, |
691 | "pg%u", unit); | ||
681 | } | 692 | } |
682 | err = 0; | 693 | err = 0; |
683 | goto out; | 694 | goto out; |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 8b9549ab4a4..673b8b2fd33 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -146,6 +146,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3}; | |||
146 | #include <linux/mtio.h> | 146 | #include <linux/mtio.h> |
147 | #include <linux/device.h> | 147 | #include <linux/device.h> |
148 | #include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ | 148 | #include <linux/sched.h> /* current, TASK_*, schedule_timeout() */ |
149 | #include <linux/smp_lock.h> | ||
149 | 150 | ||
150 | #include <asm/uaccess.h> | 151 | #include <asm/uaccess.h> |
151 | 152 | ||
@@ -189,8 +190,7 @@ module_param_array(drive3, int, NULL, 0); | |||
189 | #define ATAPI_LOG_SENSE 0x4d | 190 | #define ATAPI_LOG_SENSE 0x4d |
190 | 191 | ||
191 | static int pt_open(struct inode *inode, struct file *file); | 192 | static int pt_open(struct inode *inode, struct file *file); |
192 | static int pt_ioctl(struct inode *inode, struct file *file, | 193 | static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
193 | unsigned int cmd, unsigned long arg); | ||
194 | static int pt_release(struct inode *inode, struct file *file); | 194 | static int pt_release(struct inode *inode, struct file *file); |
195 | static ssize_t pt_read(struct file *filp, char __user *buf, | 195 | static ssize_t pt_read(struct file *filp, char __user *buf, |
196 | size_t count, loff_t * ppos); | 196 | size_t count, loff_t * ppos); |
@@ -236,7 +236,7 @@ static const struct file_operations pt_fops = { | |||
236 | .owner = THIS_MODULE, | 236 | .owner = THIS_MODULE, |
237 | .read = pt_read, | 237 | .read = pt_read, |
238 | .write = pt_write, | 238 | .write = pt_write, |
239 | .ioctl = pt_ioctl, | 239 | .unlocked_ioctl = pt_ioctl, |
240 | .open = pt_open, | 240 | .open = pt_open, |
241 | .release = pt_release, | 241 | .release = pt_release, |
242 | }; | 242 | }; |
@@ -650,8 +650,11 @@ static int pt_open(struct inode *inode, struct file *file) | |||
650 | struct pt_unit *tape = pt + unit; | 650 | struct pt_unit *tape = pt + unit; |
651 | int err; | 651 | int err; |
652 | 652 | ||
653 | if (unit >= PT_UNITS || (!tape->present)) | 653 | lock_kernel(); |
654 | if (unit >= PT_UNITS || (!tape->present)) { | ||
655 | unlock_kernel(); | ||
654 | return -ENODEV; | 656 | return -ENODEV; |
657 | } | ||
655 | 658 | ||
656 | err = -EBUSY; | 659 | err = -EBUSY; |
657 | if (!atomic_dec_and_test(&tape->available)) | 660 | if (!atomic_dec_and_test(&tape->available)) |
@@ -678,15 +681,16 @@ static int pt_open(struct inode *inode, struct file *file) | |||
678 | } | 681 | } |
679 | 682 | ||
680 | file->private_data = tape; | 683 | file->private_data = tape; |
684 | unlock_kernel(); | ||
681 | return 0; | 685 | return 0; |
682 | 686 | ||
683 | out: | 687 | out: |
684 | atomic_inc(&tape->available); | 688 | atomic_inc(&tape->available); |
689 | unlock_kernel(); | ||
685 | return err; | 690 | return err; |
686 | } | 691 | } |
687 | 692 | ||
688 | static int pt_ioctl(struct inode *inode, struct file *file, | 693 | static long pt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
689 | unsigned int cmd, unsigned long arg) | ||
690 | { | 694 | { |
691 | struct pt_unit *tape = file->private_data; | 695 | struct pt_unit *tape = file->private_data; |
692 | struct mtop __user *p = (void __user *)arg; | 696 | struct mtop __user *p = (void __user *)arg; |
@@ -700,23 +704,26 @@ static int pt_ioctl(struct inode *inode, struct file *file, | |||
700 | switch (mtop.mt_op) { | 704 | switch (mtop.mt_op) { |
701 | 705 | ||
702 | case MTREW: | 706 | case MTREW: |
707 | lock_kernel(); | ||
703 | pt_rewind(tape); | 708 | pt_rewind(tape); |
709 | unlock_kernel(); | ||
704 | return 0; | 710 | return 0; |
705 | 711 | ||
706 | case MTWEOF: | 712 | case MTWEOF: |
713 | lock_kernel(); | ||
707 | pt_write_fm(tape); | 714 | pt_write_fm(tape); |
715 | unlock_kernel(); | ||
708 | return 0; | 716 | return 0; |
709 | 717 | ||
710 | default: | 718 | default: |
711 | printk("%s: Unimplemented mt_op %d\n", tape->name, | 719 | /* FIXME: rate limit ?? */ |
720 | printk(KERN_DEBUG "%s: Unimplemented mt_op %d\n", tape->name, | ||
712 | mtop.mt_op); | 721 | mtop.mt_op); |
713 | return -EINVAL; | 722 | return -EINVAL; |
714 | } | 723 | } |
715 | 724 | ||
716 | default: | 725 | default: |
717 | printk("%s: Unimplemented ioctl 0x%x\n", tape->name, cmd); | 726 | return -ENOTTY; |
718 | return -EINVAL; | ||
719 | |||
720 | } | 727 | } |
721 | } | 728 | } |
722 | 729 | ||
@@ -972,10 +979,12 @@ static int __init pt_init(void) | |||
972 | 979 | ||
973 | for (unit = 0; unit < PT_UNITS; unit++) | 980 | for (unit = 0; unit < PT_UNITS; unit++) |
974 | if (pt[unit].present) { | 981 | if (pt[unit].present) { |
975 | device_create(pt_class, NULL, MKDEV(major, unit), | 982 | device_create_drvdata(pt_class, NULL, |
976 | "pt%d", unit); | 983 | MKDEV(major, unit), NULL, |
977 | device_create(pt_class, NULL, MKDEV(major, unit + 128), | 984 | "pt%d", unit); |
978 | "pt%dn", unit); | 985 | device_create_drvdata(pt_class, NULL, |
986 | MKDEV(major, unit + 128), NULL, | ||
987 | "pt%dn", unit); | ||
979 | } | 988 | } |
980 | goto out; | 989 | goto out; |
981 | 990 | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 3ba1df93e9e..0e077150568 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -302,7 +302,9 @@ static struct kobj_type kobj_pkt_type_wqueue = { | |||
302 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) | 302 | static void pkt_sysfs_dev_new(struct pktcdvd_device *pd) |
303 | { | 303 | { |
304 | if (class_pktcdvd) { | 304 | if (class_pktcdvd) { |
305 | pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name); | 305 | pd->dev = device_create_drvdata(class_pktcdvd, NULL, |
306 | pd->pkt_dev, NULL, | ||
307 | "%s", pd->name); | ||
306 | if (IS_ERR(pd->dev)) | 308 | if (IS_ERR(pd->dev)) |
307 | pd->dev = NULL; | 309 | pd->dev = NULL; |
308 | } | 310 | } |
@@ -2079,7 +2081,6 @@ static noinline_for_stack int pkt_write_caching(struct pktcdvd_device *pd, | |||
2079 | unsigned char buf[64]; | 2081 | unsigned char buf[64]; |
2080 | int ret; | 2082 | int ret; |
2081 | 2083 | ||
2082 | memset(buf, 0, sizeof(buf)); | ||
2083 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); | 2084 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_READ); |
2084 | cgc.sense = &sense; | 2085 | cgc.sense = &sense; |
2085 | cgc.buflen = pd->mode_offset + 12; | 2086 | cgc.buflen = pd->mode_offset + 12; |
@@ -2126,7 +2127,6 @@ static noinline_for_stack int pkt_get_max_speed(struct pktcdvd_device *pd, | |||
2126 | unsigned char *cap_buf; | 2127 | unsigned char *cap_buf; |
2127 | int ret, offset; | 2128 | int ret, offset; |
2128 | 2129 | ||
2129 | memset(buf, 0, sizeof(buf)); | ||
2130 | cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; | 2130 | cap_buf = &buf[sizeof(struct mode_page_header) + pd->mode_offset]; |
2131 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); | 2131 | init_cdrom_command(&cgc, buf, sizeof(buf), CGC_DATA_UNKNOWN); |
2132 | cgc.sense = &sense; | 2132 | cgc.sense = &sense; |
@@ -2544,7 +2544,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) | |||
2544 | if (last_zone != zone) { | 2544 | if (last_zone != zone) { |
2545 | BUG_ON(last_zone != zone + pd->settings.size); | 2545 | BUG_ON(last_zone != zone + pd->settings.size); |
2546 | first_sectors = last_zone - bio->bi_sector; | 2546 | first_sectors = last_zone - bio->bi_sector; |
2547 | bp = bio_split(bio, bio_split_pool, first_sectors); | 2547 | bp = bio_split(bio, first_sectors); |
2548 | BUG_ON(!bp); | 2548 | BUG_ON(!bp); |
2549 | pkt_make_request(q, &bp->bio1); | 2549 | pkt_make_request(q, &bp->bio1); |
2550 | pkt_make_request(q, &bp->bio2); | 2550 | pkt_make_request(q, &bp->bio2); |
@@ -2633,11 +2633,12 @@ end_io: | |||
2633 | 2633 | ||
2634 | 2634 | ||
2635 | 2635 | ||
2636 | static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_vec *bvec) | 2636 | static int pkt_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, |
2637 | struct bio_vec *bvec) | ||
2637 | { | 2638 | { |
2638 | struct pktcdvd_device *pd = q->queuedata; | 2639 | struct pktcdvd_device *pd = q->queuedata; |
2639 | sector_t zone = ZONE(bio->bi_sector, pd); | 2640 | sector_t zone = ZONE(bmd->bi_sector, pd); |
2640 | int used = ((bio->bi_sector - zone) << 9) + bio->bi_size; | 2641 | int used = ((bmd->bi_sector - zone) << 9) + bmd->bi_size; |
2641 | int remaining = (pd->settings.size << 9) - used; | 2642 | int remaining = (pd->settings.size << 9) - used; |
2642 | int remaining2; | 2643 | int remaining2; |
2643 | 2644 | ||
@@ -2645,7 +2646,7 @@ static int pkt_merge_bvec(struct request_queue *q, struct bio *bio, struct bio_v | |||
2645 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet | 2646 | * A bio <= PAGE_SIZE must be allowed. If it crosses a packet |
2646 | * boundary, pkt_make_request() will split the bio. | 2647 | * boundary, pkt_make_request() will split the bio. |
2647 | */ | 2648 | */ |
2648 | remaining2 = PAGE_SIZE - bio->bi_size; | 2649 | remaining2 = PAGE_SIZE - bmd->bi_size; |
2649 | remaining = max(remaining, remaining2); | 2650 | remaining = max(remaining, remaining2); |
2650 | 2651 | ||
2651 | BUG_ON(remaining < 0); | 2652 | BUG_ON(remaining < 0); |
@@ -2910,7 +2911,7 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) | |||
2910 | if (!disk->queue) | 2911 | if (!disk->queue) |
2911 | goto out_mem2; | 2912 | goto out_mem2; |
2912 | 2913 | ||
2913 | pd->pkt_dev = MKDEV(disk->major, disk->first_minor); | 2914 | pd->pkt_dev = MKDEV(pktdev_major, idx); |
2914 | ret = pkt_new_dev(pd, dev); | 2915 | ret = pkt_new_dev(pd, dev); |
2915 | if (ret) | 2916 | if (ret) |
2916 | goto out_new_dev; | 2917 | goto out_new_dev; |
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index d797e209951..936466f62af 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c | |||
@@ -199,7 +199,8 @@ static void ps3disk_do_request(struct ps3_storage_device *dev, | |||
199 | if (blk_fs_request(req)) { | 199 | if (blk_fs_request(req)) { |
200 | if (ps3disk_submit_request_sg(dev, req)) | 200 | if (ps3disk_submit_request_sg(dev, req)) |
201 | break; | 201 | break; |
202 | } else if (req->cmd_type == REQ_TYPE_FLUSH) { | 202 | } else if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && |
203 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
203 | if (ps3disk_submit_flush_request(dev, req)) | 204 | if (ps3disk_submit_flush_request(dev, req)) |
204 | break; | 205 | break; |
205 | } else { | 206 | } else { |
@@ -257,7 +258,8 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data) | |||
257 | return IRQ_HANDLED; | 258 | return IRQ_HANDLED; |
258 | } | 259 | } |
259 | 260 | ||
260 | if (req->cmd_type == REQ_TYPE_FLUSH) { | 261 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && |
262 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
261 | read = 0; | 263 | read = 0; |
262 | num_sectors = req->hard_cur_sectors; | 264 | num_sectors = req->hard_cur_sectors; |
263 | op = "flush"; | 265 | op = "flush"; |
@@ -405,7 +407,8 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req) | |||
405 | 407 | ||
406 | dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); | 408 | dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__); |
407 | 409 | ||
408 | req->cmd_type = REQ_TYPE_FLUSH; | 410 | req->cmd_type = REQ_TYPE_LINUX_BLOCK; |
411 | req->cmd[0] = REQ_LB_OP_FLUSH; | ||
409 | } | 412 | } |
410 | 413 | ||
411 | static unsigned long ps3disk_mask; | 414 | static unsigned long ps3disk_mask; |
@@ -538,7 +541,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev) | |||
538 | struct ps3disk_private *priv = dev->sbd.core.driver_data; | 541 | struct ps3disk_private *priv = dev->sbd.core.driver_data; |
539 | 542 | ||
540 | mutex_lock(&ps3disk_mask_mutex); | 543 | mutex_lock(&ps3disk_mask_mutex); |
541 | __clear_bit(priv->gendisk->first_minor / PS3DISK_MINORS, | 544 | __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS, |
542 | &ps3disk_mask); | 545 | &ps3disk_mask); |
543 | mutex_unlock(&ps3disk_mask_mutex); | 546 | mutex_unlock(&ps3disk_mask_mutex); |
544 | del_gendisk(priv->gendisk); | 547 | del_gendisk(priv->gendisk); |
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index dd7ea203f94..6ec5fc05278 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -47,20 +47,20 @@ static void blk_done(struct virtqueue *vq) | |||
47 | 47 | ||
48 | spin_lock_irqsave(&vblk->lock, flags); | 48 | spin_lock_irqsave(&vblk->lock, flags); |
49 | while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { | 49 | while ((vbr = vblk->vq->vq_ops->get_buf(vblk->vq, &len)) != NULL) { |
50 | int uptodate; | 50 | int error; |
51 | switch (vbr->status) { | 51 | switch (vbr->status) { |
52 | case VIRTIO_BLK_S_OK: | 52 | case VIRTIO_BLK_S_OK: |
53 | uptodate = 1; | 53 | error = 0; |
54 | break; | 54 | break; |
55 | case VIRTIO_BLK_S_UNSUPP: | 55 | case VIRTIO_BLK_S_UNSUPP: |
56 | uptodate = -ENOTTY; | 56 | error = -ENOTTY; |
57 | break; | 57 | break; |
58 | default: | 58 | default: |
59 | uptodate = 0; | 59 | error = -EIO; |
60 | break; | 60 | break; |
61 | } | 61 | } |
62 | 62 | ||
63 | end_dequeued_request(vbr->req, uptodate); | 63 | __blk_end_request(vbr->req, error, blk_rq_bytes(vbr->req)); |
64 | list_del(&vbr->list); | 64 | list_del(&vbr->list); |
65 | mempool_free(vbr, vblk->pool); | 65 | mempool_free(vbr, vblk->pool); |
66 | } | 66 | } |
@@ -84,11 +84,11 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk, | |||
84 | if (blk_fs_request(vbr->req)) { | 84 | if (blk_fs_request(vbr->req)) { |
85 | vbr->out_hdr.type = 0; | 85 | vbr->out_hdr.type = 0; |
86 | vbr->out_hdr.sector = vbr->req->sector; | 86 | vbr->out_hdr.sector = vbr->req->sector; |
87 | vbr->out_hdr.ioprio = vbr->req->ioprio; | 87 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); |
88 | } else if (blk_pc_request(vbr->req)) { | 88 | } else if (blk_pc_request(vbr->req)) { |
89 | vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; | 89 | vbr->out_hdr.type = VIRTIO_BLK_T_SCSI_CMD; |
90 | vbr->out_hdr.sector = 0; | 90 | vbr->out_hdr.sector = 0; |
91 | vbr->out_hdr.ioprio = vbr->req->ioprio; | 91 | vbr->out_hdr.ioprio = req_get_ioprio(vbr->req); |
92 | } else { | 92 | } else { |
93 | /* We don't put anything else in the queue. */ | 93 | /* We don't put anything else in the queue. */ |
94 | BUG(); | 94 | BUG(); |
@@ -196,6 +196,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
196 | int err; | 196 | int err; |
197 | u64 cap; | 197 | u64 cap; |
198 | u32 v; | 198 | u32 v; |
199 | u32 blk_size; | ||
199 | 200 | ||
200 | if (index_to_minor(index) >= 1 << MINORBITS) | 201 | if (index_to_minor(index) >= 1 << MINORBITS) |
201 | return -ENOSPC; | 202 | return -ENOSPC; |
@@ -290,6 +291,13 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
290 | if (!err) | 291 | if (!err) |
291 | blk_queue_max_hw_segments(vblk->disk->queue, v); | 292 | blk_queue_max_hw_segments(vblk->disk->queue, v); |
292 | 293 | ||
294 | /* Host can optionally specify the block size of the device */ | ||
295 | err = virtio_config_val(vdev, VIRTIO_BLK_F_BLK_SIZE, | ||
296 | offsetof(struct virtio_blk_config, blk_size), | ||
297 | &blk_size); | ||
298 | if (!err) | ||
299 | blk_queue_hardsect_size(vblk->disk->queue, blk_size); | ||
300 | |||
293 | add_disk(vblk->disk); | 301 | add_disk(vblk->disk); |
294 | return 0; | 302 | return 0; |
295 | 303 | ||
@@ -330,7 +338,7 @@ static struct virtio_device_id id_table[] = { | |||
330 | 338 | ||
331 | static unsigned int features[] = { | 339 | static unsigned int features[] = { |
332 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, | 340 | VIRTIO_BLK_F_BARRIER, VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, |
333 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, | 341 | VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE, |
334 | }; | 342 | }; |
335 | 343 | ||
336 | static struct virtio_driver virtio_blk = { | 344 | static struct virtio_driver virtio_blk = { |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index f2fff5799dd..1a50ae70f71 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
39 | #include <linux/blkdev.h> | 39 | #include <linux/blkdev.h> |
40 | #include <linux/hdreg.h> | 40 | #include <linux/hdreg.h> |
41 | #include <linux/cdrom.h> | ||
41 | #include <linux/module.h> | 42 | #include <linux/module.h> |
42 | 43 | ||
43 | #include <xen/xenbus.h> | 44 | #include <xen/xenbus.h> |
@@ -104,15 +105,17 @@ static DEFINE_SPINLOCK(blkif_io_lock); | |||
104 | #define GRANT_INVALID_REF 0 | 105 | #define GRANT_INVALID_REF 0 |
105 | 106 | ||
106 | #define PARTS_PER_DISK 16 | 107 | #define PARTS_PER_DISK 16 |
108 | #define PARTS_PER_EXT_DISK 256 | ||
107 | 109 | ||
108 | #define BLKIF_MAJOR(dev) ((dev)>>8) | 110 | #define BLKIF_MAJOR(dev) ((dev)>>8) |
109 | #define BLKIF_MINOR(dev) ((dev) & 0xff) | 111 | #define BLKIF_MINOR(dev) ((dev) & 0xff) |
110 | 112 | ||
111 | #define DEV_NAME "xvd" /* name in /dev */ | 113 | #define EXT_SHIFT 28 |
114 | #define EXTENDED (1<<EXT_SHIFT) | ||
115 | #define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED)) | ||
116 | #define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED)) | ||
112 | 117 | ||
113 | /* Information about our VBDs. */ | 118 | #define DEV_NAME "xvd" /* name in /dev */ |
114 | #define MAX_VBDS 64 | ||
115 | static LIST_HEAD(vbds_list); | ||
116 | 119 | ||
117 | static int get_id_from_freelist(struct blkfront_info *info) | 120 | static int get_id_from_freelist(struct blkfront_info *info) |
118 | { | 121 | { |
@@ -153,6 +156,40 @@ static int blkif_getgeo(struct block_device *bd, struct hd_geometry *hg) | |||
153 | return 0; | 156 | return 0; |
154 | } | 157 | } |
155 | 158 | ||
159 | static int blkif_ioctl(struct inode *inode, struct file *filep, | ||
160 | unsigned command, unsigned long argument) | ||
161 | { | ||
162 | struct blkfront_info *info = | ||
163 | inode->i_bdev->bd_disk->private_data; | ||
164 | int i; | ||
165 | |||
166 | dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n", | ||
167 | command, (long)argument); | ||
168 | |||
169 | switch (command) { | ||
170 | case CDROMMULTISESSION: | ||
171 | dev_dbg(&info->xbdev->dev, "FIXME: support multisession CDs later\n"); | ||
172 | for (i = 0; i < sizeof(struct cdrom_multisession); i++) | ||
173 | if (put_user(0, (char __user *)(argument + i))) | ||
174 | return -EFAULT; | ||
175 | return 0; | ||
176 | |||
177 | case CDROM_GET_CAPABILITY: { | ||
178 | struct gendisk *gd = info->gd; | ||
179 | if (gd->flags & GENHD_FL_CD) | ||
180 | return 0; | ||
181 | return -EINVAL; | ||
182 | } | ||
183 | |||
184 | default: | ||
185 | /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n", | ||
186 | command);*/ | ||
187 | return -EINVAL; /* same return as native Linux */ | ||
188 | } | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
156 | /* | 193 | /* |
157 | * blkif_queue_request | 194 | * blkif_queue_request |
158 | * | 195 | * |
@@ -324,6 +361,9 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) | |||
324 | /* Make sure buffer addresses are sector-aligned. */ | 361 | /* Make sure buffer addresses are sector-aligned. */ |
325 | blk_queue_dma_alignment(rq, 511); | 362 | blk_queue_dma_alignment(rq, 511); |
326 | 363 | ||
364 | /* Make sure we don't use bounce buffers. */ | ||
365 | blk_queue_bounce_limit(rq, BLK_BOUNCE_ANY); | ||
366 | |||
327 | gd->queue = rq; | 367 | gd->queue = rq; |
328 | 368 | ||
329 | return 0; | 369 | return 0; |
@@ -348,31 +388,60 @@ static int xlvbd_barrier(struct blkfront_info *info) | |||
348 | } | 388 | } |
349 | 389 | ||
350 | 390 | ||
351 | static int xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, | 391 | static int xlvbd_alloc_gendisk(blkif_sector_t capacity, |
352 | int vdevice, u16 vdisk_info, u16 sector_size, | 392 | struct blkfront_info *info, |
353 | struct blkfront_info *info) | 393 | u16 vdisk_info, u16 sector_size) |
354 | { | 394 | { |
355 | struct gendisk *gd; | 395 | struct gendisk *gd; |
356 | int nr_minors = 1; | 396 | int nr_minors = 1; |
357 | int err = -ENODEV; | 397 | int err = -ENODEV; |
398 | unsigned int offset; | ||
399 | int minor; | ||
400 | int nr_parts; | ||
358 | 401 | ||
359 | BUG_ON(info->gd != NULL); | 402 | BUG_ON(info->gd != NULL); |
360 | BUG_ON(info->rq != NULL); | 403 | BUG_ON(info->rq != NULL); |
361 | 404 | ||
362 | if ((minor % PARTS_PER_DISK) == 0) | 405 | if ((info->vdevice>>EXT_SHIFT) > 1) { |
363 | nr_minors = PARTS_PER_DISK; | 406 | /* this is above the extended range; something is wrong */ |
407 | printk(KERN_WARNING "blkfront: vdevice 0x%x is above the extended range; ignoring\n", info->vdevice); | ||
408 | return -ENODEV; | ||
409 | } | ||
410 | |||
411 | if (!VDEV_IS_EXTENDED(info->vdevice)) { | ||
412 | minor = BLKIF_MINOR(info->vdevice); | ||
413 | nr_parts = PARTS_PER_DISK; | ||
414 | } else { | ||
415 | minor = BLKIF_MINOR_EXT(info->vdevice); | ||
416 | nr_parts = PARTS_PER_EXT_DISK; | ||
417 | } | ||
418 | |||
419 | if ((minor % nr_parts) == 0) | ||
420 | nr_minors = nr_parts; | ||
364 | 421 | ||
365 | gd = alloc_disk(nr_minors); | 422 | gd = alloc_disk(nr_minors); |
366 | if (gd == NULL) | 423 | if (gd == NULL) |
367 | goto out; | 424 | goto out; |
368 | 425 | ||
369 | if (nr_minors > 1) | 426 | offset = minor / nr_parts; |
370 | sprintf(gd->disk_name, "%s%c", DEV_NAME, | 427 | |
371 | 'a' + minor / PARTS_PER_DISK); | 428 | if (nr_minors > 1) { |
372 | else | 429 | if (offset < 26) |
373 | sprintf(gd->disk_name, "%s%c%d", DEV_NAME, | 430 | sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); |
374 | 'a' + minor / PARTS_PER_DISK, | 431 | else |
375 | minor % PARTS_PER_DISK); | 432 | sprintf(gd->disk_name, "%s%c%c", DEV_NAME, |
433 | 'a' + ((offset / 26)-1), 'a' + (offset % 26)); | ||
434 | } else { | ||
435 | if (offset < 26) | ||
436 | sprintf(gd->disk_name, "%s%c%d", DEV_NAME, | ||
437 | 'a' + offset, | ||
438 | minor & (nr_parts - 1)); | ||
439 | else | ||
440 | sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME, | ||
441 | 'a' + ((offset / 26) - 1), | ||
442 | 'a' + (offset % 26), | ||
443 | minor & (nr_parts - 1)); | ||
444 | } | ||
376 | 445 | ||
377 | gd->major = XENVBD_MAJOR; | 446 | gd->major = XENVBD_MAJOR; |
378 | gd->first_minor = minor; | 447 | gd->first_minor = minor; |
@@ -546,7 +615,7 @@ static int setup_blkring(struct xenbus_device *dev, | |||
546 | 615 | ||
547 | info->ring_ref = GRANT_INVALID_REF; | 616 | info->ring_ref = GRANT_INVALID_REF; |
548 | 617 | ||
549 | sring = (struct blkif_sring *)__get_free_page(GFP_KERNEL); | 618 | sring = (struct blkif_sring *)__get_free_page(GFP_NOIO | __GFP_HIGH); |
550 | if (!sring) { | 619 | if (!sring) { |
551 | xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); | 620 | xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring"); |
552 | return -ENOMEM; | 621 | return -ENOMEM; |
@@ -661,8 +730,13 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
661 | err = xenbus_scanf(XBT_NIL, dev->nodename, | 730 | err = xenbus_scanf(XBT_NIL, dev->nodename, |
662 | "virtual-device", "%i", &vdevice); | 731 | "virtual-device", "%i", &vdevice); |
663 | if (err != 1) { | 732 | if (err != 1) { |
664 | xenbus_dev_fatal(dev, err, "reading virtual-device"); | 733 | /* go looking in the extended area instead */ |
665 | return err; | 734 | err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device-ext", |
735 | "%i", &vdevice); | ||
736 | if (err != 1) { | ||
737 | xenbus_dev_fatal(dev, err, "reading virtual-device"); | ||
738 | return err; | ||
739 | } | ||
666 | } | 740 | } |
667 | 741 | ||
668 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 742 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
@@ -703,7 +777,8 @@ static int blkif_recover(struct blkfront_info *info) | |||
703 | int j; | 777 | int j; |
704 | 778 | ||
705 | /* Stage 1: Make a safe copy of the shadow state. */ | 779 | /* Stage 1: Make a safe copy of the shadow state. */ |
706 | copy = kmalloc(sizeof(info->shadow), GFP_KERNEL); | 780 | copy = kmalloc(sizeof(info->shadow), |
781 | GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); | ||
707 | if (!copy) | 782 | if (!copy) |
708 | return -ENOMEM; | 783 | return -ENOMEM; |
709 | memcpy(copy, info->shadow, sizeof(info->shadow)); | 784 | memcpy(copy, info->shadow, sizeof(info->shadow)); |
@@ -822,9 +897,7 @@ static void blkfront_connect(struct blkfront_info *info) | |||
822 | if (err) | 897 | if (err) |
823 | info->feature_barrier = 0; | 898 | info->feature_barrier = 0; |
824 | 899 | ||
825 | err = xlvbd_alloc_gendisk(BLKIF_MINOR(info->vdevice), | 900 | err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); |
826 | sectors, info->vdevice, | ||
827 | binfo, sector_size, info); | ||
828 | if (err) { | 901 | if (err) { |
829 | xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", | 902 | xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", |
830 | info->xbdev->otherend); | 903 | info->xbdev->otherend); |
@@ -959,7 +1032,7 @@ static int blkif_release(struct inode *inode, struct file *filep) | |||
959 | struct xenbus_device *dev = info->xbdev; | 1032 | struct xenbus_device *dev = info->xbdev; |
960 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); | 1033 | enum xenbus_state state = xenbus_read_driver_state(dev->otherend); |
961 | 1034 | ||
962 | if (state == XenbusStateClosing) | 1035 | if (state == XenbusStateClosing && info->is_ready) |
963 | blkfront_closing(dev); | 1036 | blkfront_closing(dev); |
964 | } | 1037 | } |
965 | return 0; | 1038 | return 0; |
@@ -971,6 +1044,7 @@ static struct block_device_operations xlvbd_block_fops = | |||
971 | .open = blkif_open, | 1044 | .open = blkif_open, |
972 | .release = blkif_release, | 1045 | .release = blkif_release, |
973 | .getgeo = blkif_getgeo, | 1046 | .getgeo = blkif_getgeo, |
1047 | .ioctl = blkif_ioctl, | ||
974 | }; | 1048 | }; |
975 | 1049 | ||
976 | 1050 | ||
@@ -992,7 +1066,7 @@ static struct xenbus_driver blkfront = { | |||
992 | 1066 | ||
993 | static int __init xlblk_init(void) | 1067 | static int __init xlblk_init(void) |
994 | { | 1068 | { |
995 | if (!is_running_on_xen()) | 1069 | if (!xen_domain()) |
996 | return -ENODEV; | 1070 | return -ENODEV; |
997 | 1071 | ||
998 | if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) { | 1072 | if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) { |
@@ -1006,7 +1080,7 @@ static int __init xlblk_init(void) | |||
1006 | module_init(xlblk_init); | 1080 | module_init(xlblk_init); |
1007 | 1081 | ||
1008 | 1082 | ||
1009 | static void xlblk_exit(void) | 1083 | static void __exit xlblk_exit(void) |
1010 | { | 1084 | { |
1011 | return xenbus_unregister_driver(&blkfront); | 1085 | return xenbus_unregister_driver(&blkfront); |
1012 | } | 1086 | } |