From c5913f6621cc11afe1de316e76f7d9cc0055ca85 Mon Sep 17 00:00:00 2001 From: shasaror Date: Fri, 1 May 2026 01:38:59 +0530 Subject: [PATCH 1/4] Added build-deb.sh to create debian package for QUD kernel driver Signed-off-by: shasaror --- .gitignore | 3 +- scripts/linux/legacy/installer/QcDevDriver.sh | 1087 +++++++++++++++++ src/linux/RELEASES.md | 361 ++++++ src/linux/build-deb.sh | 380 ++++++ src/linux/qcom_drivers.sh | 67 +- src/linux/version.h | 2 +- 6 files changed, 1887 insertions(+), 13 deletions(-) create mode 100644 scripts/linux/legacy/installer/QcDevDriver.sh create mode 100644 src/linux/RELEASES.md create mode 100755 src/linux/build-deb.sh diff --git a/.gitignore b/.gitignore index 05fdc97..39135c3 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ [Dd]ebug/ [Rr]elease/ -RCa* \ No newline at end of file +RCa* +src/linux/build diff --git a/scripts/linux/legacy/installer/QcDevDriver.sh b/scripts/linux/legacy/installer/QcDevDriver.sh new file mode 100644 index 0000000..084ce0c --- /dev/null +++ b/scripts/linux/legacy/installer/QcDevDriver.sh @@ -0,0 +1,1087 @@ +#!/bin/bash +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +DEST_QTI_PATH=/opt/QTI/ +DEST_QUD_PATH=/opt/QTI/QUD +DEST_INS_RMNET_PATH=/opt/QTI/QUD/rmnet +DEST_INS_QDSS_PATH=/opt/QTI/QUD/diag +DEST_INF_PATH=/opt/QTI/QUD/diag/InfParser +DEST_QDSS_DAIG_PATH=/opt/QTI/QUD/diag/QdssDiag +DEST_SIGN_PATH=/opt/QTI/sign +QC_MODBIN_DIR=/sbin +QC_MAKE_DIR=/usr/bin +QC_MODULE_INF_NAME=qtiDevInf.ko +QC_MODULE_QDSS_DIAG_NAME=QdssDiag.ko +QC_MODULE_RMNET_NAME=GobiNet.ko +QC_DIAG_INF_PATH=/opt/QTI/QUD/diag/qtiser.inf +QC_QDSS_INF_PATH=/opt/QTI/QUD/diag/qdbusb.inf +QC_MODEM_INF_PATH=/opt/QTI/QUD/serial/qtimdm.inf +DEST_INS_SERIAL_PATH=/opt/QTI/QUD/serial +QC_UDEV_PATH=/etc/udev/rules.d +QC_MODULE_GOBISERIAL_NAME=GobiSerial.ko +QC_SERIAL=/lib/modules/`uname -r`/kernel/drivers/usb/serial +QC_QMI_WWAN=/lib/modules/`uname -r`/kernel/drivers/net/usb +QC_NET=/lib/modules/`uname -r`/kernel/drivers/net +QC_LN_RM_MK_DIR=/bin +MODULE_BLACKLIST=/etc/modprobe.d +OS_RELEASE="`cat /etc/os-release | grep PRETTY_NAME`" +OSName=`echo $OS_RELEASE | awk -F= '{printf $2}'` +KERNEL_VERSION=`uname -r` +GREEN='\033[0;32m' +RED='\033[0;31m' +BLUE='\033[0;34m' +CYAN='\033[0;36m' +RESET='\033[0m' + +#check and install mokutil package +if [ ! -f "$QC_MAKE_DIR/mokutil" ]; then + echo -e "${RED}Error: mokutil not found, installing..\n${RESET}" +fi + +if [ ! -f "$QC_MAKE_DIR/keyctl" ]; then + echo -e ${RED}"Error: keyutils not found, installing..\n"${RESET} +fi + +if [[ ! -f "$QC_MAKE_DIR/mokutil" ]] || [[ ! -f "$QC_MAKE_DIR/keyctl" ]]; then + if [[ $OSName =~ "Red Hat Enterprise Linux" ]]; then + sudo dnf install -y mokutil + sudo dnf install -y keyutils + fi + + if [[ $OSName =~ "Ubuntu" ]]; then + sudo apt-get install -y mokutil + sudo apt-get install -y keyutils + fi +fi + +if [[ $OSName =~ "Fedora Linux" ]]; then + sudo dnf install -y make automake gcc gcc-c++ kernel-devel +fi + +QC_SECURE_BOOT_CHECK=`mokutil --sb-state` + +if [[ $QC_SECURE_BOOT_CHECK = "SecureBoot enabled" ]]; then + QC_PUBLIC_KEY_VERIFY=`mokutil --test-key $DEST_SIGN_PATH/Signkey_pub.der` +fi + +if [ ! -d $DEST_QUD_PATH ]; then + echo -e "${RED}Error: $DEST_QUD_PATH doesn't exist. Creating Now.${RESET}" + $QC_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_QUD_PATH +fi + +if [ $# == 0 ]; then + echo -e "${RED}Usage: QCDevInstaller.sh ${RESET}" + exit 1 +else + if [ $1 == "uninstall" ]; then + echo -e "Operating System: $OSName" + echo -e "Kernel Version: "\""`uname -r`"\""" + + if [ -f ./version.h ]; then + VERSION="`grep -r '#define DRIVER_VERSION' version.h`" + DRIVER_VERSION=`echo $VERSION | awk '{printf $3}'` + echo -e "Driver Version: $DRIVER_VERSION" + elif [ -f ./BuildPackage/version.h ]; then + VERSION="`grep -r '#define DRIVER_VERSION' ./BuildPackage/version.h`" + DRIVER_VERSION=`echo $VERSION | awk '{printf $3}'` + echo -e "Driver Version: $DRIVER_VERSION" + fi + + if [ -d $DEST_INS_QDSS_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + if [ ! -d $DEST_INS_QDSS_PATH ]; then + echo -e "Successfully removed $DEST_INS_QDSS_PATH" + else + echo -e "${RED}Failed to remove $DEST_INS_QDSS_PATH${RESET}" + fi + else + echo -e "$DEST_INS_QDSS_PATH does not exist, nothing to remove" + fi + if [ -d $DEST_INS_RMNET_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + if [ ! -d $DEST_INS_RMNET_PATH ]; then + echo -e "Successfully removed $DEST_INS_RMNET_PATH" + else + echo -e "${RED}Failed to remove $DEST_INS_RMNET_PATH${RESET}" + fi + else + echo -e "$DEST_INS_RMNET_PATH does not exist, nothing to remove" + fi + if [ -d $DEST_INS_SERIAL_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_SERIAL_PATH + if [ ! -d $DEST_INS_SERIAL_PATH ]; then + echo -e "Successfully removed $DEST_INS_SERIAL_PATH" + else + echo -e "${RED}Failed to remove $DEST_INS_SERIAL_PATH${RESET}" + fi + else + echo -e "$DEST_INS_SERIAL_PATH does not exist, nothing to remove" + fi + + if [ -f $QC_UDEV_PATH/qti_usb_device.rules ]; then + rm -r $QC_UDEV_PATH/qti_usb_device.rules + if [ ! -f $QC_UDEV_PATH/qti_usb_device.rules ]; then + echo -e "Successfully removed $QC_UDEV_PATH/qti_usb_device.rules" + else + echo -e "${RED}Failed to remove $QC_UDEV_PATH/qti_usb_device.rules${RESET}" + fi + else + echo -e "$QC_UDEV_PATH/qti_usb_device.rules does not exist, nothing to remove" + fi + # < "Redundant 80-net-setup-link.rules. This code will be eliminated after few releases" + if [ -f $QC_UDEV_PATH/80-net-setup-link.rules ]; then + sed -i '/GobiQMI/d' $QC_UDEV_PATH/80-net-setup-link.rules + if [ ! -s $QC_UDEV_PATH/80-net-setup-link.rules ]; then + echo -e "Removed GobiQMI rule from $QC_UDEV_PATH/80-net-setup-link.rules" + rm -rf $QC_UDEV_PATH/80-net-setup-link.rules + if [ ! -f $QC_UDEV_PATH/80-net-setup-link.rules ]; then + echo -e "File was empty. Removed $QC_UDEV_PATH/80-net-setup-link.rules successfully" + else + echo -e "File is empty but Failed to remove $QC_UDEV_PATH/80-net-setup-link.rules" + fi + else + echo -e "Pre-Existing data $QC_UDEV_PATH/80-net-setup-link.rules, so not removing it." + fi + else + echo -e "$QC_UDEV_PATH/80-net-setup-link.rules does not exist, nothing to remove" + fi + # > + if [ -f $QC_UDEV_PATH/80-gobinet-usbdevice.rules ]; then + sed -i '/usb/d' $QC_UDEV_PATH/80-gobinet-usbdevice.rules + if [ ! -s $QC_UDEV_PATH/80-gobinet-usbdevice.rules ]; then + echo -e "Removed GobiQMI rule from $QC_UDEV_PATH/80-gobinet-usbdevice.rules" + rm -rf $QC_UDEV_PATH/80-gobinet-usbdevice.rules + if [ ! -f $QC_UDEV_PATH/80-gobinet-usbdevice.rules ]; then + echo -e "File was empty. Removed $QC_UDEV_PATH/80-gobinet-usbdevice.rules successfully" + else + echo -e "File is empty but Failed to remove $QC_UDEV_PATH/80-gobinet-usbdevice.rules" + fi + else + echo -e "Pre-Existing data $QC_UDEV_PATH/80-gobinet-usbdevice.rules, so not removing it." + fi + else + echo -e "$QC_UDEV_PATH/80-gobinet-usbdevice.rules does not exist, nothing to remove" + fi + + # Informs udev deamon to reload the newly added device rule and re-trigger service + sudo udevadm control --reload-rules + sudo udevadm trigger + + if [ "`lsmod | grep GobiSerial`" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_GOBISERIAL_NAME && echo -e "$QC_MODULE_GOBISERIAL_NAME removed successfully") || { echo -e "$QC_MODULE_GOBISERIAL_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } + else + echo -e "Module $QC_MODULE_GOBISERIAL_NAME is not currently loaded" + fi + if [ "`lsmod | grep GobiNet`" ]; then + ( $QC_MODBIN_DIR/rmmod $QC_MODULE_RMNET_NAME && echo -e "$QC_MODULE_RMNET_NAME removed successfully" ) || { echo -e "$QC_MODULE_RMNET_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } + else + echo -e "Module $QC_MODULE_RMNET_NAME is not currently loaded" + fi + if [ "`lsmod | grep QdssDiag`" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_QDSS_DIAG_NAME && echo -e "$QC_MODULE_QDSS_DIAG_NAME removed successfully") || { echo -e "$QC_MODULE_QDSS_DIAG_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } + else + echo -e "Module $QC_MODULE_QDSS_DIAG_NAME is not currently loaded" + fi + if [ "`lsmod | grep qtiDevInf`" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_INF_NAME && echo -e "$QC_MODULE_INF_NAME removed successfully") || { echo -e "$QC_MODULE_INF_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } + else + echo -e "Module $QC_MODULE_INF_NAME is not currently loaded" + fi + + MODLOADED="`/sbin/lsmod | grep usb_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "usb_wwan module is already loaded. nothing to do" + fi + if [ -f $QC_SERIAL/usb_wwan_dup* ]; then + echo -e "usb_wwan_dup is found. restoring to usb_wwan" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/usb_wwan_dup* /lib/modules/`uname -r`/kernel/drivers/usb/serial/usb_wwan.ko + #$QC_MODBIN_DIR/insmod /lib/modules/`uname -r`/kernel/drivers/usb/serial/usb_wwan.ko + + MODLOADED="`/sbin/lsmod | grep usb_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "Successfully loaded usb_wwan module." + fi + fi + + MODLOADED="`/sbin/lsmod | grep qcserial`" + if [ "$MODLOADED" != "" ]; then + echo -e "qcserial module is already loaded. nothing to do" + fi + if [ -f $QC_SERIAL/qcserial_dup* ]; then + echo -e "qcserial_dup is found. restoring to qcserial" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/qcserial_dup* /lib/modules/`uname -r`/kernel/drivers/usb/serial/qcserial.ko + #$QC_MODBIN_DIR/insmod /lib/modules/`uname -r`/kernel/drivers/usb/serial/qcserial.ko + + MODLOADED="`/sbin/lsmod | grep qcserial`" + if [ "$MODLOADED" != "" ]; then + echo -e "Successfully loaded qcserial module." + fi + fi + + MODLOADED="`/sbin/lsmod | grep option`" + if [ "$MODLOADED" != "" ]; then + echo -e "option module is already loaded. nothing to do" + fi + if [ -f $QC_SERIAL/option_dup* ]; then + echo -e "option_dup is found. restoring to option" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/option_dup* /lib/modules/`uname -r`/kernel/drivers/usb/serial/option.ko + #$QC_MODBIN_DIR/insmod /lib/modules/`uname -r`/kernel/drivers/usb/serial/option.ko + + MODLOADED="`/sbin/lsmod | grep option`" + if [ "$MODLOADED" != "" ]; then + echo -e "Successfully loaded option module." + fi + fi + + MODLOADED="`/sbin/lsmod | grep qmi_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "qmi_wwan module is already loaded. nothing to do" + fi + if [ -f $QC_QMI_WWAN/qmi_wwan_dup* ]; then + echo -e "qmi_wwan_dup is found. restoring to qmi_wwan" + mv /lib/modules/`uname -r`/kernel/drivers/usb/class/cdc-wdm_dup* /lib/modules/`uname -r`/kernel/drivers/usb/class/cdc-wdm.ko + mv /lib/modules/`uname -r`/kernel/drivers/net/usb/qmi_wwan_dup* /lib/modules/`uname -r`/kernel/drivers/net/usb/qmi_wwan.ko + #$QC_MODBIN_DIR/insmod /lib/modules/`uname -r`/kernel/drivers/usb/class/cdc-wdm.ko + #$QC_MODBIN_DIR/insmod /lib/modules/`uname -r`/kernel/drivers/net/usb/qmi_wwan.ko + + MODLOADED="`/sbin/lsmod | grep qmi_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "Successfully loaded qmi_wwan module." + fi + fi + + if [[ $OSName =~ "Ubuntu 24.04" ]]; then + if [ -f $QC_NET/mii.ko ]; then + $QC_LN_RM_MK_DIR/rm -rf $QC_NET/mii.ko + fi + if [ -f $QC_QMI_WWAN/usbnet.ko ]; then + $QC_LN_RM_MK_DIR/rm -rf $QC_QMI_WWAN/usbnet.ko + fi + fi + + if [ "`grep -nr 'Qualcomm clients' /etc/modprobe.d/blacklist.conf`" != "" ]; then + sed -i '/# Blacklist these module so that Qualcomm clients use only/d' /etc/modprobe.d/blacklist.conf + sed -i '/# GobiNet, GobiSerial, QdssDiag, qtiDevInf driver/d' /etc/modprobe.d/blacklist.conf + fi + + MOD_EXIST="`grep -nr 'blacklist qcserial' /etc/modprobe.d/blacklist.conf`" + if [ "$MOD_EXIST" != "" ]; then + sed -i '/qcserial/d' $MODULE_BLACKLIST/blacklist.conf + echo -e "Successfully removed qcserial from $MODULE_BLACKLIST/blacklist.conf" + fi + + MOD_EXIST="`grep -nr 'blacklist qmi_wwan' /etc/modprobe.d/blacklist.conf`" + if [ "$MOD_EXIST" != "" ]; then + sed -i '/qmi_wwan/d' $MODULE_BLACKLIST/blacklist.conf + echo -e "Successfully removed qmi_wwan from $MODULE_BLACKLIST/blacklist.conf" + fi + + MOD_EXIST="`grep -nr 'blacklist option' /etc/modprobe.d/blacklist.conf`" + if [ "$MOD_EXIST" != "" ]; then + sed -i '/option/d' $MODULE_BLACKLIST/blacklist.conf + echo -e "Successfully removed option from $MODULE_BLACKLIST/blacklist.conf" + fi + + MOD_EXIST="`grep -nr 'blacklist usb_wwan' /etc/modprobe.d/blacklist.conf`" + if [ "$MOD_EXIST" != "" ]; then + sed -i '/usb_wwan/d' $MODULE_BLACKLIST/blacklist.conf + echo -e "Successfully removed usb_wwan from $MODULE_BLACKLIST/blacklist.conf" + fi + + #change to permission to default mode + $QC_LN_RM_MK_DIR/chmod 644 $MODULE_BLACKLIST/blacklist.conf + + echo -e "Removing modules for /etc/modules." + MODUPDATE="`grep -r qtiDevInf /etc/modules`" + if [ "$MODUPDATE" == "qtiDevInf" ]; then + sed -i '/qtiDevInf/d' /etc/modules + fi + MODUPDATE="`grep -r QdssDiag /etc/modules`" + if [ "$MODUPDATE" == "QdssDiag" ]; then + sed -i '/QdssDiag/d' /etc/modules + fi + MODUPDATE="`grep -r GobiNet /etc/modules`" + if [ "$MODUPDATE" == "GobiNet" ]; then + sed -i '/GobiNet/d' /etc/modules + fi + MODUPDATE="`grep -r GobiSerial /etc/modules`" + if [ "$MODUPDATE" == "GobiSerial" ]; then + sed -i '/GobiSerial/d' /etc/modules + fi + if [[ $OSName != *"Red Hat Enterprise Linux"* ]]; then + MODUPDATE="`grep -nr 'iface usb0 inet static' /etc/network/interfaces`" + if [ "$MODUPDATE" != "" ]; then + sed -i '/iface usb0 inet static/d' /etc/network/interfaces + fi + fi + + echo -e "Removing modules from $QC_SERIAL" + if [ -f $QC_SERIAL/$QC_MODULE_GOBISERIAL_NAME ]; then + rm -rf $QC_SERIAL/$QC_MODULE_GOBISERIAL_NAME + fi + echo -e "Removing modules from $QC_QMI_WWAN" + if [ -f $QC_QMI_WWAN/$QC_MODULE_QDSS_DIAG_NAME ]; then + rm -rf $QC_QMI_WWAN/$QC_MODULE_QDSS_DIAG_NAME + fi + if [ -f $QC_QMI_WWAN/$QC_MODULE_RMNET_NAME ]; then + rm -rf $QC_QMI_WWAN/$QC_MODULE_RMNET_NAME + fi + if [ -f $QC_QMI_WWAN/$QC_MODULE_INF_NAME ]; then + rm -rf $QC_QMI_WWAN/$QC_MODULE_INF_NAME + fi + # update modules.dep and modules.alias + depmod + + echo -e "Uninstallation completed successfully." + exit 0 + else + if [ $1 != "install" ]; then + echo -e "Usage: QCDevInstaller.sh " + exit 1 + fi + fi +fi + +######## Installation ########### + +if [[ $OSName =~ "Ubuntu" ]]; then + sudo apt-get update + sudo apt-get install -y build-essential + sudo apt-get install -y gawk + sudo apt-get install -y python3-tk +fi + +IFS=. read -r major_ver minor_ver patch_ver <<< "$KERNEL_VERSION" +if [[ $OSName =~ "Ubuntu 22." ]] && (( $major_ver >= 6 && $minor_ver >= 5 )); then + echo -e "Installing gcc 12 version ..." + sudo apt install -y gcc-12 g++-12 +fi +if [[ $OSName =~ "Ubuntu 24." ]] && (( $major_ver >= 6 && $minor_ver >= 14 )); then + echo -e "Installing gcc 14 version ..." + sudo apt install -y gcc-14 g++-14 +fi + +echo -e "${CYAN}=======================================================================================" +echo -e "=======================================================================================${RESET}" +echo -e " " + +echo -e "Operating System:${RED} $OSName"${RESET} +echo -e "Kernel Version: ${RED}"\"$KERNEL_VERSION\"""${RESET} + +if [ -f ./version.h ]; then + VERSION="`grep -r '#define DRIVER_VERSION' version.h`" + DRIVER_VERSION=`echo $VERSION | awk '{printf $3}'` + echo -e "Driver Version: $DRIVER_VERSION" +fi + +echo -e "Installing at the following paths:" +echo $DEST_INS_SERIAL_PATH +echo $DEST_INS_QDSS_PATH +echo $DEST_INS_RMNET_PATH + +# this script will use in qik uninstallation process +if [ -f "$DEST_QUD_PATH/QcDevDriver.sh" ]; then + echo -e "Delete and copy again (QcDevDriver.sh)" + $QC_LN_RM_MK_DIR/rm -rf $DEST_QUD_PATH/QcDevDriver.sh + $QC_LN_RM_MK_DIR/cp -rf ./QcDevDriver.sh $DEST_QUD_PATH/ +else + echo -e "Does not exist and copying now.. (QcDevDriver.sh)" + $QC_LN_RM_MK_DIR/cp -rf ./QcDevDriver.sh $DEST_QUD_PATH/ +fi + +# Create directories +if [ -d $DEST_INS_SERIAL_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_SERIAL_PATH +fi + +$QC_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_INS_SERIAL_PATH +if [ ! -d $DEST_INS_SERIAL_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +if [ -d $DEST_INS_QDSS_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH +fi + +$QC_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_INS_QDSS_PATH +if [ ! -d $DEST_INS_QDSS_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +if [ -d $DEST_INF_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INF_PATH +fi + +$QC_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_INF_PATH +if [ ! -d $DEST_INF_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +if [ -d $DEST_QDSS_DAIG_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_QDSS_DAIG_PATH +fi + +$QC_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_QDSS_DAIG_PATH +if [ ! -d $DEST_QDSS_DAIG_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +# Important: Do not delete or recreate the "sign" folder. +# The sign files will be automatically generated whenever the Signpub key is not enrolled. +$QC_LN_RM_MK_DIR/mkdir -m 0777 -p $DEST_SIGN_PATH +if [ ! -d $DEST_SIGN_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +# $QC_LN_RM_MK_DIR/cp ./GobiSerial/GobiSerial.c $DEST_INS_SERIAL_PATH +# if [ ! -f $DEST_INS_SERIAL_PATH/GobiSerial.c ]; then +# echo -e "${RED}Error: Failed to copy GobiSerial.c to installation path, installation abort." +# rm -r $DEST_INS_SERIAL_PATH +# exit 1 +# fi + +# $QC_LN_RM_MK_DIR/cp ./GobiSerial/GobiSerial.h $DEST_INS_SERIAL_PATH +# if [ ! -f $DEST_INS_SERIAL_PATH/GobiSerial.h ]; then +# echo -e "${RED}Error: Failed to copy GobiSerial.h to installation path, installation abort." +# rm -r $DEST_INS_SERIAL_PATH +# exit 1 +# fi + +# $QC_LN_RM_MK_DIR/cp ./GobiSerial/Makefile $DEST_INS_SERIAL_PATH +# if [ ! -f $DEST_INS_SERIAL_PATH/Makefile ]; then +# echo -e "${RED}Error: Failed to copy Makefile installation path, installation abort." +# rm -r $DEST_INS_SERIAL_PATH +# exit 1 +# fi + +# $QC_LN_RM_MK_DIR/cp ./GobiSerial/qtidev.pl $DEST_INS_SERIAL_PATH +# if [ ! -f $DEST_INS_SERIAL_PATH/qtidev.pl ]; then +# echo -e "${RED}Error: Failed to copy qtidev.pl installation path, installation abort." +# rm -r $DEST_INS_SERIAL_PATH +# exit 1 +# fi +# $QC_LN_RM_MK_DIR/chmod 755 $DEST_INS_SERIAL_PATH/qtidev.pl + +$QC_LN_RM_MK_DIR/cp ./GobiSerial/qtiname.inf $DEST_INS_SERIAL_PATH +if [ ! -f $DEST_INS_SERIAL_PATH/qtiname.inf ]; then + echo -e "${RED}Error: Failed to copy qtiname.inf installation path, installation abort." + rm -r $DEST_INS_SERIAL_PATH + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_SERIAL_PATH/qtiname.inf + +$QC_LN_RM_MK_DIR/cp ./GobiSerial/qtimdm.inf $DEST_INS_SERIAL_PATH +if [ ! -f $DEST_INS_SERIAL_PATH/qtimdm.inf ]; then + echo -e "${RED}Error: Failed to copy qtiname.inf installation path, installation abort." + rm -r $DEST_INS_SERIAL_PATH + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_SERIAL_PATH/qtimdm.inf + + +$QC_LN_RM_MK_DIR/cp ./GobiSerial/qtiname.inf $DEST_INS_QDSS_PATH/ +if [ ! -f $DEST_INS_QDSS_PATH//qtiname.inf ]; then + echo -e "${RED}Error: Failed to copy qtiname.inf installation path, installation abort." + rm -r $DEST_INS_QDSS_PATH/ + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_SERIAL_PATH/qtiname.inf + +$QC_LN_RM_MK_DIR/cp ./GobiSerial/qtimdm.inf $DEST_INS_QDSS_PATH/ +if [ ! -f $DEST_INS_QDSS_PATH//qtimdm.inf ]; then + echo -e "${RED}Error: Failed to copy qtiname.inf installation path, installation abort." + rm -r $DEST_INS_QDSS_PATH/ + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_QDSS_PATH/qtimdm.inf + + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/qdbusb.inf $DEST_INS_QDSS_PATH/ +if [ ! -f $DEST_INS_QDSS_PATH/qdbusb.inf ]; then + echo -e "${RED}Error: Failed to copy 'qdbusb.inf' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/qtiser.inf $DEST_INS_QDSS_PATH/ +if [ ! -f $DEST_INS_QDSS_PATH/qtiser.inf ]; then + echo -e "${RED}Error: Failed to copy 'qtiser.inf' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_QDSS_PATH/qdbusb.inf +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_QDSS_PATH/qtiser.inf + +$QC_LN_RM_MK_DIR/cp ./InfParser/qtiDevInf.h $DEST_INF_PATH/ +if [ ! -f $DEST_INF_PATH/qtiDevInf.h ]; then + echo -e "${RED}Error: Failed to copy 'InfParser/qtiDevInf.h' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./InfParser/qtiDevInf.c $DEST_INF_PATH/ +if [ ! -f $DEST_INF_PATH/qtiDevInf.c ]; then + echo -e "${RED}Error: Failed to copy 'InfParser/qtiDevInf.c' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./InfParser/Makefile $DEST_INF_PATH/ +if [ ! -f $DEST_INF_PATH/Makefile ]; then + echo -e "${RED}Error: Failed to copy 'InfParser/Makefile' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/qtiDevInf.h $DEST_QDSS_DAIG_PATH/ +if [ ! -f $DEST_QDSS_DAIG_PATH/qtiDevInf.h ]; then + echo -e "${RED}Error: Failed to copy 'QdssDiag/qtiDevInf.h' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/qtiDiag.h $DEST_QDSS_DAIG_PATH/ +if [ ! -f $DEST_QDSS_DAIG_PATH/qtiDiag.h ]; then + echo -e "${RED}Error: Failed to copy 'QdssDiag/qtiDiag.h' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/qtiDiag.c $DEST_QDSS_DAIG_PATH/ +if [ ! -f $DEST_QDSS_DAIG_PATH/qtiDiag.c ]; then + echo -e "${RED}Error: Failed to copy 'QdssDiag/qtiDiag.c' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./Makefile $DEST_QDSS_DAIG_PATH/ +if [ ! -f $DEST_QDSS_DAIG_PATH/Makefile ]; then + echo -e "${RED}Error: Failed to copy 'QdssDiag/Makefile' to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + exit 1 +fi + +if [ -d $DEST_INS_RMNET_PATH ]; then + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH +fi + +$QC_LN_RM_MK_DIR/mkdir -p $DEST_INS_RMNET_PATH +if [ ! -d $DEST_INS_RMNET_PATH ]; then + echo -e "${RED}Error: Failed to create installation path, please run installer under root." + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/IPAssignmentScript.sh $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/IPAssignmentScript.sh ]; then + echo -e "${RED}Error: Failed to copy IPAssignmentScript.sh to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/chmod 755 $DEST_INS_RMNET_PATH/IPAssignmentScript.sh + +$QC_LN_RM_MK_DIR/cp ./rmnet/GobiUSBNet.c $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/GobiUSBNet.c ]; then + echo -e "${RED}Error: Failed to copy GobiUSBNet.c to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/QMIDevice.c $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/QMIDevice.c ]; then + echo -e "${RED}Error: Failed to copy QMIDevice.c to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/QMIDevice.h $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/QMIDevice.h ]; then + echo -e "${RED}Error: Failed to copy QMIDevice.h to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/QMI.c $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/QMI.c ]; then + echo -e "${RED}Error: Failed to copy QMI.c to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/QMI.h $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/QMI.h ]; then + echo -e "${RED}Error: Failed to copy QMI.h to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/qmap.c $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/qmap.c ]; then + echo -e "${RED}Error: Failed to copy qmap.c to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/qmap.h $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/qmap.h ]; then + echo -e "${RED}Error: Failed to copy qmap.h to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/Structs.h $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/Structs.h ]; then + echo -e "${RED}Error: Failed to copy Structs.h to installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/Makefile $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/Makefile ]; then + echo -e "${RED}Error: Failed to copy Makefile installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/qtiwwan.inf $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/qtiwwan.inf ]; then + echo -e "${RED}Error: Failed to copy qtiwwan.inf installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_INS_RMNET_PATH/qtiwwan.inf + +#DEST_SIGN_PATH=/opt/QTI/sign/ +$QC_LN_RM_MK_DIR/cp ./sign/SignConf.config $DEST_SIGN_PATH +$QC_LN_RM_MK_DIR/chmod 777 $DEST_SIGN_PATH/SignConf.config +awk -i inplace -v name=`hostname` '{gsub(/O = /,"O = "name)}1' $DEST_SIGN_PATH/SignConf.config +awk -i inplace -v name=`hostname` '{gsub(/CN = /,"CN = "name" Signing Key")}1' $DEST_SIGN_PATH/SignConf.config +awk -i inplace -v name=`hostname` '{gsub(/emailAddress = /,"emailAddress = "name"@no-reply.com")}1' $DEST_SIGN_PATH/SignConf.config + +if [ ! -f $DEST_SIGN_PATH/SignConf.config ]; then + echo -e "${RED}Error: Failed to copy SignConf.config installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_SIGN_PATH + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./sign/signReadme.txt $DEST_SIGN_PATH +if [ ! -f $DEST_SIGN_PATH/signReadme.txt ]; then + echo -e "${RED}Error: Failed to copy signReadme.txt installation path, installation abort." + $QC_LN_RM_MK_DIR/rm -rf $DEST_SIGN_PATH + exit 1 +fi +$QC_LN_RM_MK_DIR/chmod 644 $DEST_SIGN_PATH/signReadme.txt + + +if [[ $QC_SECURE_BOOT_CHECK = "SecureBoot enabled" ]]; then + echo -e "${RED}SecureBoot enabled" + if [ -f $DEST_SIGN_PATH/Signkey_pub.der ]; then + if [[ $QC_PUBLIC_KEY_VERIFY = "$DEST_SIGN_PATH/Signkey_pub.der is already enrolled" ]]; then + echo -e "${CYAN}===========================================================" + echo -e "${GREEN}$DEST_SIGN_PATH/Signkey_pub.der is enrolled" + echo -e "${CYAN}===========================================================${RESET}" + else + echo -e "${RED}===========================================================" + echo -e "${CYAN}Secure Boot is enabled. User must enroll the Public Signkey located at /opt/QTI/sign/Signkey_pub.der" + echo -e "${CYAN}Please follow the mandatory instructions in /opt/QTI/sign/signReadme.txt" + echo -e "${CYAN}The QUD driver installation Failed!!!" + echo -e "${RED}===========================================================${RESET}" + exit 1 + fi + else + echo -e "${RED}Signkey_pub.der doesn't exist. Creating public and private key${RESET}" + openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 -batch -config $DEST_SIGN_PATH/SignConf.config -outform DER -out $DEST_SIGN_PATH/Signkey_pub.der -keyout $DEST_SIGN_PATH/Signkey.priv + $QC_LN_RM_MK_DIR/chmod 755 $DEST_SIGN_PATH/Signkey_pub.der + $QC_LN_RM_MK_DIR/chmod 755 $DEST_SIGN_PATH/Signkey.priv + echo -e "${RED}##############################################################" + echo -e "${CYAN}Secure Boot is enabled. User must enroll the Public Signkey located at /opt/QTI/sign/Signkey_pub.der" + echo -e "${CYAN}Please follow the mandatory instructions in /opt/QTI/sign/signReadme.txt" + echo -e "${CYAN}The QUD driver installation Failed!!!" + echo -e "${RED}##############################################################${RESET}" + exit 1 + fi +else + echo -e "${GREEN}Secure boot disabled${RESET}" +fi + +# "********************* Compilation of modules Starts ***************************" +$QC_MAKE_DIR/make install +if [ ! -f ./InfParser/$QC_MODULE_INF_NAME ]; then + echo -e "${RED}Error: Failed to generate kernel module $QC_MODULE_INF_NAME, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + $QC_MAKE_DIR/make clean + exit 1 +fi +if [ ! -f ./QdssDiag/$QC_MODULE_QDSS_DIAG_NAME ]; then + echo -e "${RED}Error: Failed to generate kernel module $QC_MODULE_QDSS_DIAG_NAME, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + $QC_MAKE_DIR/make clean + exit 1 +fi + +if [ ! -f ./rmnet/$QC_MODULE_RMNET_NAME ]; then + echo -e "${RED}Error: Failed to generate kernel module $QC_MODULE_RMNET_NAME, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + $QC_MAKE_DIR/make clean + exit 1 +fi + +# if [ ! -f ./GobiSerial/$QC_MODULE_GOBISERIAL_NAME ]; then +# echo -e "${RED}Error: Failed to generate kernel module $QC_MODULE_GOBISERIAL_NAME, installation abort." +# $QC_LN_RM_MK_DIR/rm -rf $QC_MODULE_GOBISERIAL_NAME +# $QC_MAKE_DIR/make clean +# exit 1 +# fi + +# Copy .ko object to destination folders +# $QC_LN_RM_MK_DIR/cp ./GobiSerial/$QC_MODULE_GOBISERIAL_NAME $DEST_INS_SERIAL_PATH +# if [ ! -f $DEST_INS_SERIAL_PATH/$QC_MODULE_GOBISERIAL_NAME ]; then +# echo -e "${RED}Error: Failed to copy $QC_MODULE_GOBISERIAL_NAME to installation path, installation abort." +# $QC_LN_RM_MK_DIR/rm -r $DEST_INS_SERIAL_PATH +# $QC_MAKE_DIR/make clean +# exit 1 +# fi + +$QC_LN_RM_MK_DIR/cp ./InfParser/$QC_MODULE_INF_NAME $DEST_INF_PATH +if [ ! -f $DEST_INF_PATH/$QC_MODULE_INF_NAME ]; then + echo -e "${RED}Error: Failed to copy $QC_MODULE_INF_NAME to installation path, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + $QC_MAKE_DIR/make clean + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./QdssDiag/$QC_MODULE_QDSS_DIAG_NAME $DEST_QDSS_DAIG_PATH +if [ ! -f $DEST_QDSS_DAIG_PATH/$QC_MODULE_QDSS_DIAG_NAME ]; then + echo -e "${RED}Error: Failed to copy $QC_MODULE_QDSS_DIAG_NAME to installation path, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_QDSS_PATH + $QC_MAKE_DIR/make clean + exit 1 +fi + +$QC_LN_RM_MK_DIR/cp ./rmnet/$QC_MODULE_RMNET_NAME $DEST_INS_RMNET_PATH +if [ ! -f $DEST_INS_RMNET_PATH/$QC_MODULE_RMNET_NAME ]; then + echo -e "${RED}Error: Failed to copy $QC_MODULE_RMNET_NAME to installation path, installation abort.${RESET}" + $QC_LN_RM_MK_DIR/rm -rf $DEST_INS_RMNET_PATH + exit 1 +fi + +$QC_MAKE_DIR/make clean + +# echo SUBSYSTEMS==\"tty\", PROGRAM=\"$DEST_INS_SERIAL_PATH/qtidev.pl $DEST_INS_SERIAL_PATH/qtiname.inf %k\", SYMLINK+=\"%c\" , MODE=\"0666\" > ./qti_usb_device.rules +echo SUBSYSTEMS==\"GobiQMI\", MODE=\"0666\" >> ./qti_usb_device.rules +echo SUBSYSTEMS==\"GobiUSB\", MODE=\"0666\" >> ./qti_usb_device.rules +echo SUBSYSTEMS==\"GobiPorts\", MODE=\"0666\" >> ./qti_usb_device.rules + +$QC_LN_RM_MK_DIR/chmod 644 ./qti_usb_device.rules +$QC_LN_RM_MK_DIR/cp ./qti_usb_device.rules $QC_UDEV_PATH +echo -e "Generated QC rules" + +# udev rules for QMI +if [ -f $QC_UDEV_PATH/80-gobinet-usbdevice.rules ]; then + RULE_EXIST="`grep -nr 'usb' $QC_UDEV_PATH/80-gobinet-usbdevice.rules`" + if [ "$RULE_EXIST" != "" ]; then + echo -e "Subsystem GobiQMI rule already exist in $QC_UDEV_PATH/80-gobinet-usbdevice.rules, nothing to add" + else + echo -e "Subsystem GobiQMI rule doesn't exist in $QC_UDEV_PATH/80-gobinet-usbdevice.rules, so adding now" + $QC_LN_RM_MK_DIR/chmod 644 $QC_UDEV_PATH/80-gobinet-usbdevice.rules + echo SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"05c6\", NAME=\"usb%n\" >> $QC_UDEV_PATH/80-gobinet-usbdevice.rules + fi +else + echo SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"05c6\", NAME=\"usb%n\" >> ./80-gobinet-usbdevice.rules + $QC_LN_RM_MK_DIR/chmod 644 ./80-gobinet-usbdevice.rules + $QC_LN_RM_MK_DIR/cp ./80-gobinet-usbdevice.rules $QC_UDEV_PATH + echo -e "Creating new udev rule for GobiQMI in $QC_UDEV_PATH/80-gobinet-usbdevice.rules" +fi + +#Informs udev deamon to reload the newly added device rule and re-trigger service +sudo udevadm control --reload-rules +sudo udevadm trigger + +if [ ! -f $QC_UDEV_PATH/qti_usb_device.rules ]; then + echo -e "${RED}Error: Failed to generate $QC_UDEV_PATH/qti_usb_device.rules" + exit 1 +fi + +if [ ! -f $QC_UDEV_PATH/80-gobinet-usbdevice.rules ]; then + echo -e "${RED}Error: Failed to generate $QC_UDEV_PATH/80-gobinet-usbdevice.rules" + exit 1 +fi + +rm -f ./qti_usb_device.rules +rm -f ./80-net-setup-link.rules +rm -f ./80-gobinet-usbdevice.rules +echo -e "Removed local rules" + +MODLOADED="`/sbin/lsmod | grep usbserial`" +if [ "$MODLOADED" == "" ]; then + echo -e "To load dependency" + echo -e "Loading module usbserial" + if [[ $OSName =~ "Red Hat Enterprise Linux" ]]; then + if [ -f $QC_SERIAL/usbserial.ko.xz ]; then + xz -d $QC_SERIAL/usbserial.ko.xz + $QC_MODBIN_DIR/insmod $QC_SERIAL/usbserial.ko + fi + MODLOADED="`/sbin/lsmod | grep usbserial`" + if [ "$MODLOADED" == "" ]; then + echo -e "$OSName: usbserial.ko module not present at $QC_SERIAL" + fi + else + $QC_MODBIN_DIR/insmod $QC_SERIAL/usbserial.ko + fi +else + echo -e "Module usbserial already in place" +fi + +#echo Changing Permission of blacklist file +$QC_LN_RM_MK_DIR/chmod 777 $MODULE_BLACKLIST/blacklist.conf +echo -e "Changed Permission of blacklist file" +if [ "`grep -nr 'Qualcomm clients' /etc/modprobe.d/blacklist.conf`" != "" ]; then + sed -i '/# Blacklist these module so that Qualcomm clients use only/d' /etc/modprobe.d/blacklist.conf + sed -i '/# GobiNet, GobiSerial, QdssDiag, qtiDevInf driver/d' /etc/modprobe.d/blacklist.conf +fi +echo -e "# Blacklist these module so that Qualcomm clients use only" >> /etc/modprobe.d/blacklist.conf +echo -e "# GobiNet, GobiSerial, QdssDiag, qtiDevInf driver" >> /etc/modprobe.d/blacklist.conf + +MOD_EXIST="`grep -nr 'blacklist qcserial' /etc/modprobe.d/blacklist.conf`" +if [ "$MOD_EXIST" != "" ]; then + sed -i '/qcserial/d' $MODULE_BLACKLIST/blacklist.conf +fi +echo -e "blacklist qcserial" >> /etc/modprobe.d/blacklist.conf +echo -e "install qcserial /bin/false" >> /etc/modprobe.d/blacklist.conf +echo -e "blacklisted qcserial module" + +MODLOADED="`/sbin/lsmod | grep qcserial`" +if [ "$MODLOADED" != "" ]; then + echo -e "qcserial is found. Unloaded qcserial module" + $QC_MODBIN_DIR/rmmod qcserial.ko + MODLOADED="`/sbin/lsmod | grep qcserial`" + if [ "$MODLOADED" != "" ]; then + echo -e "${RED}Failed to unload qcserial.ko. try manually sudo rmmod ModuleName${RESET}" + fi +fi +if [ -f $QC_SERIAL/qcserial.ko ]; then + echo -e "qcserial is found. renamed to qcserial_dup" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/qcserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/qcserial_dup +fi + +MOD_EXIST="`grep -nr 'blacklist qmi_wwan' /etc/modprobe.d/blacklist.conf`" +if [ "$MOD_EXIST" != "" ]; then + sed -i '/qmi_wwan/d' $MODULE_BLACKLIST/blacklist.conf +fi +echo -e "blacklist qmi_wwan" >> /etc/modprobe.d/blacklist.conf +echo -e "install qmi_wwan /bin/false" >> /etc/modprobe.d/blacklist.conf +echo -e "blacklisted qmi_wwan module" + +MODLOADED="`/sbin/lsmod | grep qmi_wwan`" +if [ "$MODLOADED" != "" ]; then + echo -e "qmi_wwan is found. Unloaded qmi_wwan module" + echo -e "cdc-wdm is found. Unloaded cdc-wdm module" + $QC_MODBIN_DIR/rmmod qmi_wwan.ko + $QC_MODBIN_DIR/rmmod cdc-wdm.ko + MODLOADED="`/sbin/lsmod | grep qmi_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "${RED}Failed to unload qmi_wwan.ko. Run manually sudo rmmod ModuleName${RESET}" + fi + MODLOADED="`/sbin/lsmod | grep cdc_wdm`" + if [ "$MODLOADED" != "" ]; then + echo -e "${RED}Failed to unload cdc_wdm.ko. Run manually sudo rmmod ModuleName${RESET}" + fi +fi +if [ -f $QC_QMI_WWAN/qmi_wwan.ko ]; then + echo -e "qmi_wwan is found. renamed to qmi_wwan_dup" + echo -e "cdc-wdm is found. renamed to cdc-wdm_dup" + mv /lib/modules/`uname -r`/kernel/drivers/usb/class/cdc-wdm.ko /lib/modules/`uname -r`/kernel/drivers/usb/class/cdc-wdm_dup + mv /lib/modules/`uname -r`/kernel/drivers/net/usb/qmi_wwan.ko /lib/modules/`uname -r`/kernel/drivers/net/usb/qmi_wwan_dup +fi + +MOD_EXIST="`grep -nr 'blacklist option' /etc/modprobe.d/blacklist.conf`" +if [ "$MOD_EXIST" != "" ]; then + sed -i '/option/d' $MODULE_BLACKLIST/blacklist.conf +fi +echo -e "blacklist option" >> /etc/modprobe.d/blacklist.conf +echo -e "install option /bin/false" >> /etc/modprobe.d/blacklist.conf +echo -e "blacklisted option module" + +MODLOADED="`/sbin/lsmod | grep option`" +if [ "$MODLOADED" != "" ]; then + echo -e "option is found. Unloaded option module" + $QC_MODBIN_DIR/rmmod option.ko + MODLOADED="`/sbin/lsmod | grep option`" + if [ "$MODLOADED" != "" ]; then + echo -e "${RED}Failed to unload option.ko. Run manually sudo rmmod option${RESET}" + fi +fi +if [ -f $QC_SERIAL/option.ko ]; then + echo -e "option is found. renamed to to option_dup" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/option.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/option_dup +fi + +MOD_EXIST="`grep -nr 'blacklist usb_wwan' /etc/modprobe.d/blacklist.conf`" +if [ "$MOD_EXIST" != "" ]; then + sed -i '/usb_wwan/d' $MODULE_BLACKLIST/blacklist.conf +fi +echo -e "blacklist usb_wwan" >> /etc/modprobe.d/blacklist.conf +echo -e "install usb_wwan /bin/false" >> /etc/modprobe.d/blacklist.conf +echo -e "blacklisted usb_wwan module" + +MODLOADED="`/sbin/lsmod | grep usb_wwan`" +if [ "$MODLOADED" != "" ]; then + echo -e "usb_wwan is found. Unloaded usb_wwan module" + $QC_MODBIN_DIR/rmmod usb_wwan.ko + MODLOADED="`/sbin/lsmod | grep usb_wwan`" + if [ "$MODLOADED" != "" ]; then + echo -e "${RED}Failed to unload usb_wwan.ko. Run manually sudo rmmod ModuleName${RESET}" + fi +fi +if [ -f $QC_SERIAL/usb_wwan.ko ]; then + echo -e "usb_wwan is found. renamed to usb_wwan_dup" + mv /lib/modules/`uname -r`/kernel/drivers/usb/serial/usb_wwan.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/usb_wwan_dup +fi + +MODLOADED="`/sbin/lsmod | grep GobiSerial`" +if [ "$MODLOADED" != "" ]; then + ( $QC_MODBIN_DIR/rmmod $QC_MODULE_GOBISERIAL_NAME && echo -e "$QC_MODULE_GOBISERIAL_NAME removed successfully.." ) || { echo -e "$QC_MODULE_GOBISERIAL_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } +fi + +# echo -e "Loading module $QC_MODULE_GOBISERIAL_NAME" +# $QC_MODBIN_DIR/insmod $DEST_INS_SERIAL_PATH/$QC_MODULE_GOBISERIAL_NAME gQTIModemInfFilePath=$QC_MODEM_INF_PATH debug=0 + +MODLOADED="`/sbin/lsmod | grep QdssDiag`" +if [ "$MODLOADED" != "" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_QDSS_DIAG_NAME && echo -e "$QC_MODULE_QDSS_DIAG_NAME removed successfully..") || { echo -e "$QC_MODULE_QDSS_DIAG_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } +fi + +echo -e "Loading module dependency" +MODLOADED="`/sbin/lsmod | grep mii`" +if [ "$MODLOADED" == "" ]; then + echo -e "Loading module mii" + if [[ $OSName =~ "Red Hat Enterprise Linux" ]] || [[ $OSName =~ "Fedora Linux" ]] || [[ $OSName =~ "Ubuntu 24.04" ]] || [[ $OSName =~ "CentOS" ]]; then + if [ -f $QC_NET/mii.ko.xz ]; then + xz -d $QC_NET/mii.ko.xz + fi + if [ -f $QC_NET/mii.ko.zst ]; then + unzstd -d $QC_NET/mii.ko.zst + fi + if [ -f $QC_NET/mii.ko ]; then + $QC_MODBIN_DIR/insmod $QC_NET/mii.ko + fi + MODLOADED="`/sbin/lsmod | grep mii`" + if [ "$MODLOADED" == "" ]; then + echo -e "$OSName: mii.ko module not present at $QC_NET" + fi + else + $QC_MODBIN_DIR/insmod $QC_NET/mii.ko + fi +else + echo -e "Module mii already in place" +fi + +MODLOADED="`/sbin/lsmod | grep usbnet`" +if [ "$MODLOADED" == "" ]; then + echo -e "Loading module usbnet" + if [[ $OSName =~ "Red Hat Enterprise Linux" ]] || [[ $OSName =~ "Fedora Linux" ]] || [[ $OSName =~ "Ubuntu 24.04" ]] || [[ $OSName =~ "CentOS" ]]; then + if [ -f $QC_QMI_WWAN/usbnet.ko.xz ]; then + xz -d $QC_QMI_WWAN/usbnet.ko.xz + fi + if [ -f $QC_QMI_WWAN/usbnet.ko.zst ]; then + unzstd -d $QC_QMI_WWAN/usbnet.ko.zst + fi + if [ -f $QC_QMI_WWAN/usbnet.ko ]; then + $QC_MODBIN_DIR/insmod $QC_QMI_WWAN/usbnet.ko + fi + MODLOADED="`/sbin/lsmod | grep usbnet`" + if [ "$MODLOADED" == "" ]; then + echo -e "$OSName: usbnet.ko module not present at $QC_QMI_WWAN" + fi + else + $QC_MODBIN_DIR/insmod $QC_QMI_WWAN/usbnet.ko + fi +else + echo -e "Module usbnet already in place" +fi + +MODLOADED="`/sbin/lsmod | grep GobiNet`" +if [ "$MODLOADED" != "" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_RMNET_NAME && echo -e "$QC_MODULE_RMNET_NAME removed successfully..") || { echo -e "$QC_MODULE_RMNET_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } +fi + +MODLOADED="`/sbin/lsmod | grep qtiDevInf`" +if [ "$MODLOADED" != "" ]; then + ($QC_MODBIN_DIR/rmmod $QC_MODULE_INF_NAME && echo -e "$QC_MODULE_INF_NAME removed successfully..") || { echo -e "$QC_MODULE_INF_NAME in use"; echo -e "${RED}Note: ${CYAN} Close all applications that make use of the driver, including QUTS clients."; echo -e "${RED}ps -aux | grep QUTS, sudo kill -9 OR sudo pkill QUTS"; echo -e "${GREEN}Try $1ation again!"; exit 1; } +fi + +echo -e "Loading new module $QC_MODULE_INF_NAME" +$QC_MODBIN_DIR/insmod $DEST_INF_PATH/$QC_MODULE_INF_NAME debug_g=0 +MODLOADED="`/sbin/lsmod | grep qtiDevInf`" +if [ "$MODLOADED" == "" ]; then + echo -e "${RED}Failed to load new $QC_MODULE_INF_NAME module${RESET}" + exit 1 +fi +echo -e "Loading new module $QC_MODULE_QDSS_DIAG_NAME" +$QC_MODBIN_DIR/insmod $DEST_QDSS_DAIG_PATH/$QC_MODULE_QDSS_DIAG_NAME gQdssInfFilePath=$QC_QDSS_INF_PATH gDiagInfFilePath=$QC_DIAG_INF_PATH debug_g=0 +MODLOADED="`/sbin/lsmod | grep QdssDiag`" +if [ "$MODLOADED" == "" ]; then + echo -e "${RED}Failed to load new $QC_MODULE_INF_NAME module${RESET}" + exit 1 +fi +echo -e "Loading new module $QC_MODULE_RMNET_NAME" +$QC_MODBIN_DIR/insmod $DEST_INS_RMNET_PATH/$QC_MODULE_RMNET_NAME debug_g=0 debug_aggr=0 +MODLOADED="`/sbin/lsmod | grep GobiNet`" +if [ "$MODLOADED" == "" ]; then + echo -e "${RED}Failed to load new $QC_MODULE_INF_NAME module${RESET}" + exit 1 +fi +#update modules.dep and modules.alias +depmod + +$QC_MAKE_DIR/find $DEST_QTI_PATH -type d -exec chmod 0755 {} \; + +echo -e "Qualcomm GobiNet driver is installed at $DEST_INS_RMNET_PATH" +echo -e "Qualcomm INF Parser driver is installed at $DEST_INF_PATH" +echo -e "Qualcomm QDSS/Diag driver is installed at $DEST_QDSS_DAIG_PATH" +echo -e "Qualcomm Modem driver is installed at $DEST_INS_SERIAL_PATH" +echo -e "Qualcomm Gobi device naming rules are installed at $QC_UDEV_PATH" + +if [ -f "$DEST_QUD_PATH/ReleaseNotes*.txt" ]; then + echo -e "QUD Release Notes available at $DEST_QUD_PATH" +fi + +MODUPDATE="`grep -r QCDevInf /etc/modules`" +if [ "$MODUPDATE" == "QCDevInf" ]; then + sed -i '/QCDevInf/d' /etc/modules +fi +MODUPDATE="`grep -nr qtiDevInf /etc/modules`" +if [ "$MODUPDATE" == "" ]; then + echo -e "qtiDevInf" >> /etc/modules +fi + +MODUPDATE="`grep -nr QdssDiag /etc/modules`" +if [ "$MODUPDATE" == "" ]; then + echo -e "QdssDiag" >> /etc/modules +fi + +MODUPDATE="`grep -nr GobiNet /etc/modules`" +if [ "$MODUPDATE" == "" ]; then + echo -e "GobiNet" >> /etc/modules +fi + +# MODUPDATE="`grep -nr GobiSerial /etc/modules`" +# if [ "$MODUPDATE" == "" ]; then +# echo -e "GobiSerial" >> /etc/modules +# fi + +if [[ $OSName != *"Red Hat Enterprise Linux"* ]]; then + MODUPDATE="`grep -nr 'iface usb0 inet static' /etc/network/interfaces`" + if [ "$MODUPDATE" == "" ]; then + echo -e "iface usb0 inet static" >> /etc/network/interfaces + fi +fi + +exit 0 diff --git a/src/linux/RELEASES.md b/src/linux/RELEASES.md new file mode 100644 index 0000000..09dccf3 --- /dev/null +++ b/src/linux/RELEASES.md @@ -0,0 +1,361 @@ +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +# Release Notes + +All notable changes to the **Qualcomm USB Kernel Drivers (QUD)** project are documented in this file. + +## Component Description + +Qualcomm USB host drivers providing logical representations of Qualcomm chipset-enabled mobile devices over USB connection (Only for Qualcomm users). + +- **Open source repository:** https://github.com/qualcomm/qcom-usb-kernel-drivers.git +- **Public QUD Wiki Reference:** https://qwiki.qualcomm.com/public/Qct-linux-usb-host-drivers +- **Contacts:** `` — For any question or comment regarding QUD driver. +- **Contributing:** If you are interested in contributing to the open-source Qualcomm USB Kernel Driver, please refer to [CONTRIBUTING.md](../../CONTRIBUTING.md), or raise an issue on GitHub for any query. + +## Tools + +`QMIConnectionManager` App (A tool facilities QMI calls via the Rmnet driver): + +- For older releases (below 1.0.6.0): `/opt/QTI/QUD/tools/rmnet/rmnet_QMICall` +- For newer releases (1.0.6.0 and above): `/opt/qcom/QUD/tools/rmnet/rmnet_QMICall` + +--- + +## [1.0.6.0] - 2026-03-10 + +1. Major release after the open-source migration. +2. Enhanced the makefile scripts for open-source users to build, install, and uninstall individual or multiple driver modules without relying on `qcom_drivers.sh`. This enables users to modify, test and debug modules independently, providing a cleaner and faster workflow for development and validation. +3. Fixed the post-installation QUDService script creation failure. +4. Support newer kernel version `6.6.14.0-63.fc42.x86_64` for Fedora FC42. +5. Enable support of CentOS 9 platform. + +## [1.0.5.6] + +1. Support newer kernel version 6.14 for Ubuntu and Fedora platform. + +## [1.0.5.5] + +1. Resolved use-after-free issue in GobiNet (RMNET) driver during disconnect event. Fix synchronization `ReleaseClient` function, which triggered a race condition in `NotifyAndPopNotifyList`. + +## [1.0.5.4] + +1. Resolved an issue in QUDService to ensure the QUD driver installs properly when the kernel version changes after a system reboot. +2. Addressed an installation hung issue on Ubuntu 24 while decompressing dependent kernel modules. + +## [1.0.5.0] + +1. Fixed page allocation failure issue due to large physical contiguous memory of 2^10 order. + +## [1.1.35.3] (BETA) + +1. Support for Ubuntu 24. +2. Fix race condition scenario between probe and disconnect event. +3. Fix stop read urb during disconnect event. + +## [1.1.35.2] (BETA) + +1. Fix a rare issue where "submitting an URB while active" could cause a driver crash. + +## [1.1.35.1] (BETA) + +1. Fix keyutils installation issue. +2. Fix wrong device node exposed by `qcom_usb` driver in crash mode. + +## [1.1.35.0] (BETA) + +1. The `qcom_usb` driver is now fully compliant with kernel open-source standards. +2. Device probing speed for both `qcom_usb` and `qcom_usbnet` drivers has been significantly improved by removing Infparser module dependencies, reducing kernel memory usage by 16,384 bytes and ensuring cleaner kernel logs. +3. Resolved a rare driver crash caused by internal memory fragmentation. +4. Optimized the `qcom_usb` driver, reducing the kernel memory footprint by 61,440 bytes. +5. Improved power management by addressing the runtime PM usage undercount issue. +6. Improved efficiency by implementing kernel `list_head` for the notify list instead of maintaining a custom list. +7. Simplified the driver installation process, allowing users to modify and test individual drivers faster and more efficiently without relying on the `qcom_drivers.sh` installer script. Detailed steps are provided in the README.md located at `/opt/qcom/QUD/`. +8. Minimized spin lock usage, enhancing overall concurrency and system responsiveness in both the `qcom_usb` and `qcom_usbnet` drivers. +9. Fixed an issue to prevent I/O operations from being triggered during disconnect events. + +**Note:** +- The `QdssDiag` driver is now renamed to `qcom_usb`. +- The `GobiNet` driver is now renamed to `qcom_usbnet`. +- The `qtiDevInf` module is now deprecated and no longer required. + +## [1.0.4.39] + +1. Added incompatibility QUD userspace component in installer. + +## [1.0.4.35] + +1. Support for Ubuntu 24. +2. DRYRUNCR-3293: Fix keyutils installation issue. + +## [1.0.4.34] + +1. Fixed compilation issues for kernel subversion `5.15.x.xxx`. + +## [1.0.4.32] + +1. Major improvements in GobiNet driver. Addressing crash issues and optimizing spin lock timing to enhance system responsiveness. +2. New PID Support `913C`, `912C` (IPC Router). + +## [1.0.4.31] + +1. Disabled v1.0.4.30 due to QPM backend issues. Releasing new v1.0.4.31. + +## [1.0.4.30] + +1. Publish QUD for arm64 platform. +2. Fix diag issues. +3. Added fedora utility command. + +## [1.0.4.29] + +1. Fix auto-reload of blacklisted `qcserial` and `qmi_wwan` driver. +2. Fix read/write routine being triggered after a disconnect event. +3. Added Fedora support. +4. Fixed Mac UTM issues. +5. Fixed compilation issues for ubuntu kernel `5.15.0-119` version. + +## [1.0.4.28] + +1. Fixed QMIConnectionManager glibc issue. +2. Resolved issues when pcat build download progress halts at 25%. + +## [1.0.4.27] + +1. Fix compilation of drivers for kernel version 5.15.149 and above. + +## [1.0.4.26] + +1. Added support to kernel version 6.8. + +## [1.0.4.25] + +1. Fixed rmnet driver crash issue during disconnect event. +2. Resolved gcc version mismatch issue on new ubuntu machine. + +## [1.0.4.24] + +1. Fixes of GobiNet driver for new ubuntu patch `5.15.0-94-generic`. + +## [1.0.4.23] + +1. Provided support for kernel 6.5 version. +2. Fixes for QMI Mux logging issue. + +## [1.0.4.22] + +1. Bug fixes in QdssDiag driver. +2. Resolved keyutils missing package issue and enhanced sign readme document. + +## [1.0.4.21] + +1. Implemented QUDService for installing the QUD driver in case of a kernel upgrade or change. +2. Implemented the ability to compile and install QUD driver from the `/opt/QTI/QUD` directory. + +## [1.0.4.20] + +1. Expanded QMIConnectionManager App compatibility to Ubuntu 22. +2. Enhanced QdssDiag driver by incorporating modem interface support. +3. Fixed minor issues for kernel version 5.15. +4. Support newer kernel version 6.2. + +## [1.0.4.19] + +1. QUD-857, QUD-878 and QUD-882: Public Signkey generation Issue Resolved due to awk version compatibility. +2. QUD-821: QMIConnectionManager Executable: A tool facilitating QMI calls via the Rmnet driver. FDI, please refer readme and release notes located at `/opt/QTI/QUD/tools/rmnet/rmnet_QMICall`. +3. QUD-859, QUD-870, and QUD-833: Enhanced Installation and Release Processes. +4. QUD-852: Resolved "Open Denied" Refcount Issue in QdssDiag Driver. +5. Debug Message Priorities Updated. +6. Public Qwiki Updated: For the latest information, please visit https://qwiki.qualcomm.com/public/Qct-linux-usb-host-drivers. + +## [1.0.4.18] + +1. QUD-739, QUD-817: The udev rule conflict resulted in the loss of machine network connectivity (Google). +2. QUD-844: The Linux host became unresponsive due to a crash in the QDSS driver. +3. QUD-851: A minor issue related to qpm was addressed to prevent it from displaying drivers as installed when the script fails. +4. QUD-829: The Linux QUD drivers experienced abrupt halts. +5. QUD-732: The UDP/TCP throughput in the rmnet driver was significantly improved. +6. QUD-782: Added persistent logging support for the RMNET driver. +7. QUD-742: Enhanced the logic for handling missing sequence numbers in the rmnet driver. + +## [1.0.4.17] + +1. QUD-779: Fixed rmnet gobinet kthread exit issue during disconnect events. +2. QUD-756, 755, 795: Level logging that enables users to disable global logging and dynamically control logging levels. +3. QUD-813: Loading MBN items through pcat. Fixed Async calls in rmnet driver. +4. QUD-785: Support Ubuntu 22.04 (kernel version - `5.15.0-71`). + +## [1.0.4.16] + +1. QUD-733, QUD-748: Resolved various memory leaks problems that were leading to page allocation failure for the DIAG driver. +2. QUD-746: Resolved various memory leaks problems in RMNET driver. +3. QUD-715: Wrong IP assignment to mux adapter in rmnet driver. +4. QUD-753: Added IP down feature in rmnet driver. +5. QUD-698: Implemented ReadSyncTimeout feature to address lsusb hang problem. +6. QUD-776: We updated build script to install build-essential packages to avoid unnecessary build issue on fresh machine. +7. QUD-726: The third-party tool dependency was eliminated for QUD packaging to support all Linux distributions. +8. QUD-770: Resolved ScriptRunError while upgrading QUD in Linux PC. +9. QUD-780: Fixed RMNET dev nodes creation issue in multiple devices scenario. +10. QUD-552: Fixed error message prints in QDSS and RMNET driver. +11. STARDUST-5380: Fixed all security concerns raised by stardust team. + +## [1.0.4.15] + +- Minor bug in QUD external. + +## [1.0.4.14] + +- Enable Persistent logging which ensures the debug value remains set after reboot of device. +- Enable QUD support for redhat platform. Tested on kernel version `4.18.0-372`. +- Fixes for signing the kernel module if secure boot enabled. +- Critical race condition fixes in Qdss diag write operation. + +## [1.0.3.22] + +- Disabling qcserial installation while machine is up. + +## [1.0.3.21] + +- Installation fixes. + +## [1.0.3.20] + +- Muting rmnet release due to stability issues and fix for oldfs issue. + +## [1.0.3.19] + +- Implemented buffer based memory management for rmnet drivers. + +## [1.0.3.18] + +- Linked list changes in rmnet drivers and enabling rmnet in release. + +## [1.0.3.17] + +- Added logging mechanism based on interfaces. + +## [1.0.3.16] + +- Handled error code check during re-submit. + +## [1.0.3.15] + +- Handling watchDog issue in StopRead. + +## [1.0.3.14] + +- Increased TX timeout value and handled for retry code. + +## [1.0.3.13] + +- Lock up issue fixes. + +## [1.0.3.12] + +- Major bug fixes. + +## [1.0.3.11] + +- Sync operation implementation. + +## [1.0.3.10] + +- Disabling RMNET driver. +- Linked list rework. + +## [1.0.3.9] + +- Enabling RMNET driver and minor bug fixes. + +## [1.0.3.8] + +- Major rework on ring-buffer implementation and minor stability fixes. + +## [1.0.3.7] + +- Staging build release with PR#164. +- Rework of ring-buffer for QdssDiag driver. +- Staging release with successful crashdump collection and software download. + +## [1.0.3.6] + +- Staging build release with PR#164. +- Rework of ring-buffer for QdssDiag driver. +- Staging release with successful crashdump collection. + +## [1.0.3.5] + +- Staging build release with PR#164. +- Rework of ring-buffer for QdssDiag driver. + +## [1.0.3.4] + +- Bug fixes. + +## [1.0.3.2] + +- Bug fixes and change in method of version number update. + +## [1.0.3.0] + +- Bug fixes, version number updates and Copyright details update. + +## [1.0.2.0] + +- Multiple bug fixes. + +## [1.0.1.0] + +- New release component on QPM Linux. Update installer package for clean up of previous installations. + +## [1.0.0.27] + +- Update installer package to take care of root access while installation. + +## [1.0.0.26] + +- Open Source Naming convention changes and bug fixes. + +## [1.0.0.25] + +- Added uninstallation feature in installer. + +## [1.0.0.24] + +- Added new device compositions for available devices. + +## [1.0.0.23] + +- Fixed bugs in installer and Kernel version issues. + +## [1.0.0.22] + +- Updated Kona USB composition and also replaced linux conf files with win7 conf. + +## [1.0.0.21] + +- QUD qik package directly inserts drivers modules into kernel. + +## [1.0.0.20] + +- Installer file format issues. + +## [1.0.0.19] + +- Installer Permission issues. + +## [1.0.0.18] + +1. Adding qceserial to blacklist.conf. +2. First Production release. + +## [1.0.0.17] + +1. `copy_to_user` not supposed to be used after acquiring spinlock. + +## [1.0.0.16] + +1. Resource Temporarily un-available. +2. Spin Lock Crash. +3. Adding qcserial to blacklisting files. diff --git a/src/linux/build-deb.sh b/src/linux/build-deb.sh new file mode 100755 index 0000000..be85d71 --- /dev/null +++ b/src/linux/build-deb.sh @@ -0,0 +1,380 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ----------------------------------------------------------------------------- +# build-deb.sh +# Builds a .deb package that installs Qualcomm USB kernel drivers. +# +# - Packs the entire qcom-usb-kernel-drivers/src/linux folder into the package +# - All files are installed under /opt/qcom/QUD +# - Executes qcom_drivers.sh install during package installation +# - Executes qcom_drivers.sh uninstall during package removal +# - Version is read from version.h (DRIVER_VERSION) +# - Output: ./build/qud__all.deb +# +# Usage: +# ./build-deb.sh +# +# Customization via env vars: +# PKG_NAME (default: qud) +# VERSION (default: parsed from version.h) +# ARCH (default: all) +# MAINTAINER (default: "Maintainer ") +# DESCRIPTION (default: generic description) +# INSTALL_PREFIX (default: /opt/qcom/QUD) +# OUTPUT_DIR (default: ./build) +# NO_CLEANUP=1 to keep build workdir for inspection +# +# Verify payload: dpkg-deb -c build/qud__all.deb +# Query version: dpkg -s qud | grep -i ^Version +# Install: sudo dpkg -i build/qud__all.deb +# Uninstall: sudo dpkg -r qud +# ----------------------------------------------------------------------------- + +PKG_NAME="${PKG_NAME:-qud}" + +# Resolve directories relative to this script +BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SRC_DIR="$BASE_DIR" +OUTPUT_DIR="${OUTPUT_DIR:-$BASE_DIR/build}" + +# Repo root (two levels up from src/linux) +REPO_ROOT="$(cd "$BASE_DIR/../.." && pwd)" + +LEGACY_SCRIPT_SRC="${LEGACY_SCRIPT_SRC:-$REPO_ROOT/scripts/linux/legacy/installer/QcDevDriver.sh}" + +RELEASES_SRC="$SRC_DIR/RELEASES.md" +if [ ! -f "$RELEASES_SRC" ]; then + echo "ERROR: RELEASES.md not found at $RELEASES_SRC" >&2 + echo "Aborting debian package creation." >&2 + exit 1 +fi + +# Parse version from version.h if not explicitly provided +if [ -z "${VERSION:-}" ]; then + if [ -f "$SRC_DIR/version.h" ]; then + VERSION="$(grep -E '^[[:space:]]*#define[[:space:]]+DRIVER_VERSION' "$SRC_DIR/version.h" \ + | head -n1 | sed -E 's/.*"([^"]+)".*/\1/')" + fi +fi +if [ -z "${VERSION:-}" ]; then + echo "ERROR: Could not determine VERSION from $SRC_DIR/version.h" >&2 + exit 1 +fi + +ARCH="${ARCH:-all}" +MAINTAINER="${MAINTAINER:-Maintainer }" +DESCRIPTION="${DESCRIPTION:-Qualcomm USB kernel drivers for QUD devices. Installs kernel driver sources and helper scripts, builds and loads the drivers during installation via qcom_drivers.sh.}" +INSTALL_ROOT="${INSTALL_ROOT:-/opt/qcom/QUD}" +INSTALL_PREFIX="${INSTALL_PREFIX:-$INSTALL_ROOT/build}" + +# Map ARCH to a valid Debian architecture +DEB_ARCH="$ARCH" +case "$(echo "$ARCH" | tr '[:upper:]' '[:lower:]')" in + linux-anycpu|anycpu|any|noarch|all) DEB_ARCH="all" ;; + x86_64|x64|amd64) DEB_ARCH="amd64" ;; + aarch64|arm64) DEB_ARCH="arm64" ;; + armhf) DEB_ARCH="armhf" ;; + i386|x86) DEB_ARCH="i386" ;; + *) ;; +esac + +# Pre-flight checks +if ! command -v dpkg-deb >/dev/null 2>&1; then + echo "ERROR: dpkg-deb not found. Please run on a Debian/Ubuntu host with dpkg installed." >&2 + exit 1 +fi + +if [ ! -f "$SRC_DIR/qcom_drivers.sh" ]; then + echo "ERROR: Missing required script: $SRC_DIR/qcom_drivers.sh" >&2 + exit 1 +fi +if [ ! -f "$SRC_DIR/version.h" ]; then + echo "ERROR: Missing required file: $SRC_DIR/version.h" >&2 + exit 1 +fi + +# Create working build directories +WORKDIR="$(mktemp -d -t "${PKG_NAME}-build-XXXXXX")" +BUILDROOT="$WORKDIR/${PKG_NAME}_${VERSION}" +trap 'if [ "${NO_CLEANUP:-0}" -ne 1 ]; then rm -rf "$WORKDIR"; else echo "Keeping workdir: $WORKDIR"; fi' EXIT + +mkdir -p "$BUILDROOT/DEBIAN" +mkdir -p "$BUILDROOT$INSTALL_PREFIX" +mkdir -p "$OUTPUT_DIR" +chmod 0755 "$BUILDROOT/DEBIAN" +chmod 0755 "$BUILDROOT$INSTALL_PREFIX" + +# Pack everything located at qcom-usb-kernel-drivers/src/linux into the package build payload. +# Expected contents: InfParser Makefile qcom_drivers.sh qcom_serial qcom_usb qcom_usbnet +# README.md RELEASES.md sign version.h +# Exclude only: build/ (local output) and build-deb.sh (the packaging script itself). +# On install these are unpacked under /opt/qcom/QUD. +echo "Copying driver sources from $SRC_DIR -> $BUILDROOT$INSTALL_PREFIX" +shopt -s dotglob nullglob +for entry in "$SRC_DIR"/*; do + name="$(basename "$entry")" + case "$name" in + build|build-deb.sh) continue ;; + esac + cp -a "$entry" "$BUILDROOT$INSTALL_PREFIX/" +done +shopt -u dotglob nullglob + +# Remove any kernel build artifacts that slipped in (in case user ran `make` locally) +find "$BUILDROOT$INSTALL_PREFIX" \( \ + -name '*.o' -o -name '*.ko' -o -name '*.mod' -o -name '*.mod.c' \ + -o -name '*.cmd' -o -name 'Module.symvers' -o -name 'modules.order' \ + -o -name '.tmp_versions' \) -exec rm -rf {} + 2>/dev/null || true + +# Sanity check: qcom_drivers.sh must end up in the payload +if [ ! -f "$BUILDROOT$INSTALL_PREFIX/qcom_drivers.sh" ]; then + echo "ERROR: qcom_drivers.sh was not copied into the package payload." >&2 + echo "Expected: $BUILDROOT$INSTALL_PREFIX/qcom_drivers.sh" >&2 + echo "Aborting debian package creation." >&2 + exit 1 +fi +echo "Payload top-level contents (will be installed under $INSTALL_PREFIX):" +ls -la "$BUILDROOT$INSTALL_PREFIX/" + +# Include README.md in the package payload (prefer src/linux, fallback repo root) +if [ -f "$SRC_DIR/README.md" ]; then + install -m 0644 "$SRC_DIR/README.md" "$BUILDROOT$INSTALL_PREFIX/README.md" +elif [ -f "$REPO_ROOT/README.md" ]; then + install -m 0644 "$REPO_ROOT/README.md" "$BUILDROOT$INSTALL_PREFIX/README.md" +else + echo "NOTE: README.md not found, skipping." +fi + +install -m 0644 "$RELEASES_SRC" "$BUILDROOT$INSTALL_PREFIX/RELEASES.md" + +# Bundle legacy installer helper +if [ -f "$LEGACY_SCRIPT_SRC" ]; then + mkdir -p "$BUILDROOT$INSTALL_PREFIX/legacy/installer" + install -m 0755 "$LEGACY_SCRIPT_SRC" "$BUILDROOT$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" +else + echo "NOTE: Legacy installer script not found at $LEGACY_SCRIPT_SRC, skipping." +fi + +# Ensure scripts are executable +chmod 0755 "$BUILDROOT$INSTALL_PREFIX/qcom_drivers.sh" || true +find "$BUILDROOT$INSTALL_PREFIX" -type f -name '*.sh' -exec chmod 0755 {} \; || true + +# Create DEBIAN/control +cat > "$BUILDROOT/DEBIAN/control" < "$BUILDROOT/DEBIAN/preinst" <&2 + echo " The 'qud' kernel driver package conflicts with it and cannot be installed" >&2 + echo " alongside. Please remove it first and retry:" >&2 + echo " sudo dpkg -r qualcomm-userspace-driver" >&2 + echo " or (to resolve automatically):" >&2 + echo " sudo apt-get install ./qud_${VERSION}_${DEB_ARCH}.deb" >&2 + exit 1 +fi + +mkdir -p "\$INSTALL_ROOT" || true + +# Remove any previous extracted build folder so we start fresh +if [ -d "\$INSTALL_PREFIX" ]; then + rm -rf "\$INSTALL_PREFIX" || true +fi +mkdir -p "\$INSTALL_PREFIX" || true + +if [ -e "\$LOG_FILE" ]; then + rm -f "\$LOG_FILE" || true +fi +touch "\$LOG_FILE" || true +chmod 0644 "\$LOG_FILE" || true + +exit 0 +EOF +chmod 0755 "$BUILDROOT/DEBIAN/preinst" + +# Create DEBIAN/postinst - run qcom_drivers.sh install +cat > "$BUILDROOT/DEBIAN/postinst" </dev/null || true +chmod +x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" 2>/dev/null || true + +USERSPACE_STATUS="\$(dpkg-query -W -f='\${Status}' qualcomm-userspace-driver 2>/dev/null || true)" +if [ "\$USERSPACE_STATUS" = "install ok installed" ]; then + echo "[QUD] qualcomm-userspace-driver is installed. Removing it before installing QUD kernel driver..." >> "\$LOG_FILE" 2>&1 + DEBIAN_FRONTEND=noninteractive dpkg --remove --force-remove-reinstreq qualcomm-userspace-driver >> "\$LOG_FILE" 2>&1 || \\ + DEBIAN_FRONTEND=noninteractive dpkg --purge --force-remove-reinstreq qualcomm-userspace-driver >> "\$LOG_FILE" 2>&1 || true +else + echo "[QUD] qualcomm-userspace-driver is not installed, skipping removal." >> "\$LOG_FILE" 2>&1 +fi + +# Uninstall any QUD driver previously installed via qpm-cli +if command -v qpm-cli >/dev/null 2>&1; then + QUD_INTERNAL_VERSION="\$(qpm-cli --info qud.internal 2>/dev/null | grep "Installed" | awk '{printf \$4}')" + QUD_EXTERNAL_VERSION="\$(qpm-cli --info qud 2>/dev/null | grep "Installed" | awk '{printf \$4}')" + QUD_SLT_VERSION="\$(qpm-cli --info qud.slt 2>/dev/null | grep "Installed" | awk '{printf \$4}')" + + if [ -n "\$QUD_INTERNAL_VERSION" ] || [ -n "\$QUD_EXTERNAL_VERSION" ] || [ -n "\$QUD_SLT_VERSION" ]; then + if [ -n "\$QUD_INTERNAL_VERSION" ]; then + echo "[QUD] Uninstalling qud.internal (\$QUD_INTERNAL_VERSION) via qpm-cli..." >> "\$LOG_FILE" 2>&1 + qpm-cli --uninstall qud.internal --silent --force >> "\$LOG_FILE" 2>&1 || true + fi + if [ -n "\$QUD_EXTERNAL_VERSION" ]; then + echo "[QUD] Uninstalling qud (\$QUD_EXTERNAL_VERSION) via qpm-cli..." >> "\$LOG_FILE" 2>&1 + qpm-cli --uninstall qud --silent --force >> "\$LOG_FILE" 2>&1 || true + fi + if [ -n "\$QUD_SLT_VERSION" ]; then + echo "[QUD] Uninstalling qud.slt (\$QUD_SLT_VERSION) via qpm-cli..." >> "\$LOG_FILE" 2>&1 + qpm-cli --uninstall qud.slt --silent --force >> "\$LOG_FILE" 2>&1 || true + fi + else + echo "The User hasn't installed QUD driver via qpm-cli" >> "\$LOG_FILE" 2>&1 + fi +else + echo "[QUD] qpm-cli not available, skipping qpm-cli QUD uninstall." >> "\$LOG_FILE" 2>&1 +fi + +# Legacy QUD service cleanup +QC_SYSTEMD_PATH=/etc/systemd/system +if [ -f \$QC_SYSTEMD_PATH/QUDService.service ]; then + systemctl daemon-reload >> "\$LOG_FILE" 2>&1 || true + systemctl stop QUDService >> "\$LOG_FILE" 2>&1 || true + systemctl disable QUDService.service >> "\$LOG_FILE" 2>&1 || true + rm -rf \$QC_SYSTEMD_PATH/QUDService.service >> "\$LOG_FILE" 2>&1 || true +elif [ ! -f \$QC_SYSTEMD_PATH/QUDService.service ]; then + echo "\$QC_SYSTEMD_PATH/QUDService.service unit file Doesn't exist" >> "\$LOG_FILE" 2>&1 +else + echo "Error: Failed to delete \$QC_SYSTEMD_PATH/QUDService.service" >> "\$LOG_FILE" 2>&1 +fi + +# New QUD service cleanup +QCOM_SYSTEMD_PATH=/etc/systemd/system +QCOM_QUDSERVICE=qcom-qud.service +if [ -f \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE ]; then + systemctl daemon-reload >> "\$LOG_FILE" 2>&1 || true + systemctl stop \$QCOM_QUDSERVICE >> "\$LOG_FILE" 2>&1 || true + systemctl disable \$QCOM_QUDSERVICE >> "\$LOG_FILE" 2>&1 || true + rm -rf \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE >> "\$LOG_FILE" 2>&1 || true +elif [ ! -f \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE ]; then + echo "\$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE unit file Doesn't exist" >> "\$LOG_FILE" 2>&1 +else + echo "Error: Failed to delete \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE" >> "\$LOG_FILE" 2>&1 +fi + +if [ -x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" ]; then + "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" uninstall >> "\$LOG_FILE" 2>&1 || true +fi + +# Ensure kernel headers are available for the running kernel before building modules. +KREL="\$(uname -r)" +if [ ! -d "/lib/modules/\$KREL/build" ]; then + echo "[QUD] Kernel headers for \$KREL not found, attempting to install linux-headers-\$KREL..." >> "\$LOG_FILE" 2>&1 + apt-get install -y "linux-headers-\$KREL" >> "\$LOG_FILE" 2>&1 || true +fi + +echo "[QUD] Executing qcom_drivers.sh install from \$INSTALL_PREFIX..." >> "\$LOG_FILE" 2>&1 +if [ -x "\$INSTALL_PREFIX/qcom_drivers.sh" ]; then + (cd "\$INSTALL_PREFIX" && "\$INSTALL_PREFIX/qcom_drivers.sh" install) >> "\$LOG_FILE" 2>&1 \\ + || echo "[QUD] WARNING: qcom_drivers.sh install returned non-zero exit." >> "\$LOG_FILE" 2>&1 +else + echo "[QUD] ERROR: \$INSTALL_PREFIX/qcom_drivers.sh not found or not executable." >> "\$LOG_FILE" 2>&1 +fi + +exit 0 +EOF +chmod 0755 "$BUILDROOT/DEBIAN/postinst" + +# Create DEBIAN/prerm - run qcom_drivers.sh uninstall +cat > "$BUILDROOT/DEBIAN/prerm" <> "\$LOG_FILE" 2>&1 +echo "[QUD] Running uninstall hook..." >> "\$LOG_FILE" 2>&1 +if [ -x "\$INSTALL_PREFIX/qcom_drivers.sh" ]; then + cd "\$INSTALL_PREFIX" || true + "\$INSTALL_PREFIX/qcom_drivers.sh" uninstall >> "\$LOG_FILE" 2>&1 \\ + || echo "[QUD] WARNING: qcom_drivers.sh uninstall returned non-zero exit." >> "\$LOG_FILE" 2>&1 +else + echo "[QUD] ERROR: \$INSTALL_PREFIX/qcom_drivers.sh not found or not executable." >> "\$LOG_FILE" 2>&1 +fi +exit 0 +EOF +chmod 0755 "$BUILDROOT/DEBIAN/prerm" + +# Create DEBIAN/postrm - final cleanup after uninstall +cat > "$BUILDROOT/DEBIAN/postrm" <> "\$LOG_FILE" 2>&1 || true + rm -f "\$INSTALL_ROOT/qcom_drivers.sh" >> "\$LOG_FILE" 2>&1 || true + rm -rf "\$INSTALL_PREFIX" >> "\$LOG_FILE" 2>&1 || true + ;; +esac + +exit 0 +EOF +chmod 0755 "$BUILDROOT/DEBIAN/postrm" + +# Build the .deb -> qud__all.deb +OUTPUT_DEB="$OUTPUT_DIR/${PKG_NAME}_${VERSION}_${DEB_ARCH}.deb" +echo "Building package -> $OUTPUT_DEB" +if dpkg-deb --help 2>&1 | grep -q -- '--root-owner-group'; then + dpkg-deb --build --root-owner-group "$BUILDROOT" "$OUTPUT_DEB" +else + dpkg-deb --build "$BUILDROOT" "$OUTPUT_DEB" +fi + +echo "Successfully built: $OUTPUT_DEB" +echo "Install with: sudo dpkg -i \"$OUTPUT_DEB\"" +echo "Uninstall with: sudo dpkg -r $PKG_NAME" +echo "Query version: dpkg -s $PKG_NAME | grep -i ^Version" diff --git a/src/linux/qcom_drivers.sh b/src/linux/qcom_drivers.sh index b2f76cc..e0e3ac9 100755 --- a/src/linux/qcom_drivers.sh +++ b/src/linux/qcom_drivers.sh @@ -36,6 +36,43 @@ RED='\033[0;31m' BLUE='\033[0;34m' CYAN='\033[0;36m' RESET='\033[0m' +IN_DPKG_MAINTSCRIPT="${DPKG_MAINTSCRIPT_PACKAGE:-}" + +# Since Debian package installation already holds the dpkg front‑end lock (used by apt-get), +# this script must not install dependencies when invoked by a parent dpkg process. +# Dependency installation should be handled via the Debian package metadata instead. + +apt_update_if_allowed() { + if [ -n "$IN_DPKG_MAINTSCRIPT" ]; then + echo "[QUD] Skipping 'apt-get update' (running under dpkg maintainer script)." + return 0 + fi + sudo apt-get update +} + +apt_install_if_allowed() { + if [ -n "$IN_DPKG_MAINTSCRIPT" ]; then + echo "[QUD] Skipping 'apt-get install $*' (running under dpkg maintainer script; packages are installed via Depends)." + return 0 + fi + sudo apt-get install -y "$@" +} + +apt_install_plain_if_allowed() { + if [ -n "$IN_DPKG_MAINTSCRIPT" ]; then + echo "[QUD] Skipping 'apt install $*' (running under dpkg maintainer script; packages are installed via Depends)." + return 0 + fi + sudo apt install -y "$@" +} + +dnf_install_if_allowed() { + if [ -n "$IN_DPKG_MAINTSCRIPT" ]; then + echo "[QUD] Skipping 'dnf install $*' (running under dpkg maintainer script)." + return 0 + fi + sudo dnf install -y "$@" +} #check and install mokutil package if [ ! -f "$QCOM_MAKE_DIR/mokutil" ]; then @@ -48,18 +85,18 @@ fi if [[ ! -f "$QCOM_MAKE_DIR/mokutil" ]] || [[ ! -f "$QCOM_MAKE_DIR/keyctl" ]]; then if [[ $OSName =~ "Red Hat Enterprise Linux" ]]; then - sudo dnf install -y mokutil - sudo dnf install -y keyutils + dnf_install_if_allowed mokutil + dnf_install_if_allowed keyutils fi if [[ $OSName =~ "Ubuntu" ]]; then - sudo apt-get install -y mokutil - sudo apt-get install -y keyutils + apt_install_if_allowed mokutil + apt_install_if_allowed keyutils fi fi if [[ $OSName =~ "Fedora Linux" ]]; then - sudo dnf install -y make automake gcc gcc-c++ kernel-devel + dnf_install_if_allowed make automake gcc gcc-c++ kernel-devel fi QCOM_SECURE_BOOT_CHECK=`mokutil --sb-state` @@ -103,6 +140,10 @@ else echo -e "Driver Version: $DRIVER_VERSION" fi + if [ -f $DEST_QUD_PATH/Makefile ]; then + $QCOM_LN_RM_MK_DIR/rm -rf $DEST_QUD_PATH/Makefile + fi + if [ -d $DEST_QCOM_USB_PATH ]; then $QCOM_LN_RM_MK_DIR/rm -rf $DEST_QCOM_USB_PATH if [ ! -d $DEST_QCOM_USB_PATH ]; then @@ -366,20 +407,20 @@ fi ######## Installation ########### if [[ $OSName =~ "Ubuntu" ]]; then - sudo apt-get update - sudo apt-get install -y build-essential - sudo apt-get install -y gawk - sudo apt-get install -y python3-tk + apt_update_if_allowed + apt_install_if_allowed build-essential + apt_install_if_allowed gawk + apt_install_if_allowed python3-tk fi IFS=. read -r major_ver minor_ver patch_ver <<< "$KERNEL_VERSION" if [[ $OSName =~ "Ubuntu 22." ]] && (( $major_ver >= 6 && $minor_ver >= 5 )); then echo -e "Installing gcc 12 version ..." - sudo apt install -y gcc-12 g++-12 + apt_install_plain_if_allowed gcc-12 g++-12 fi if [[ $OSName =~ "Ubuntu 24." ]] && (( $major_ver >= 6 && $minor_ver >= 14 )); then echo -e "Installing gcc 14 version ..." - sudo apt install -y gcc-14 g++-14 + apt_install_plain_if_allowed gcc-14 g++-14 fi echo -e "${CYAN}=======================================================================================" @@ -425,6 +466,10 @@ if [ -d $DEST_QCOM_USB_PATH ]; then $QCOM_LN_RM_MK_DIR/rm -rf $DEST_QCOM_USB_PATH fi +if [ -f $DEST_QUD_PATH/Makefile ]; then + $QCOM_LN_RM_MK_DIR/rm -rf $DEST_QUD_PATH/Makefile +fi + $QCOM_LN_RM_MK_DIR/mkdir -m 0755 -p $DEST_QCOM_USB_PATH if [ ! -d $DEST_QCOM_USB_PATH ]; then echo -e ${RED}"Error: Failed to create installation path: $DEST_QCOM_USB_PATH"${RESET} diff --git a/src/linux/version.h b/src/linux/version.h index 95ed94c..1e34c76 100644 --- a/src/linux/version.h +++ b/src/linux/version.h @@ -5,5 +5,5 @@ #ifndef VERSION_H #define VERSION_H -#define DRIVER_VERSION "1.0.6.0" +#define DRIVER_VERSION "1.0.6.2" #endif From 8b6048b2b2dff4d2012039aa83ce293bdd06b79f Mon Sep 17 00:00:00 2001 From: shasaror Date: Wed, 6 May 2026 10:57:44 +0530 Subject: [PATCH 2/4] Fix dpkg lock-frontend conflict issue while removing userspace driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, our QUD Debian kernel installer attempted to remove the qualcomm-userspace-driver package using dpkg purge as part of its installation flow. However, this approach led to failures and installer hangs. When the QUD kernel installer is executed,dpkg already holds an exclusive frontend lock on: /var/lib/dpkg/lock-frontend As a result, any nested attempt within the same installer script to invoke package management commands—such as: dpkg -r / dpkg --purge apt remove / apt purge will fail and may cause the installer process to hang with the following error: "dpkg: error: dpkg frontend lock was locked by another process" This behavior is by design according to Debian policy: A package must not attempt to manipulate other packages during its own installation lifecycle. Solution: Now, 'qualcomm-userspace-driver' is removed by dpkg itself before postinst runs, via the Conflicts/Replaces/Breaks fields declared in DEBIAN/control. Signed-off-by: shasaror --- src/linux/build-deb.sh | 89 ++++++++++++++++++++++++++++-------------- 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/src/linux/build-deb.sh b/src/linux/build-deb.sh index be85d71..3a249fd 100755 --- a/src/linux/build-deb.sh +++ b/src/linux/build-deb.sh @@ -19,7 +19,7 @@ set -euo pipefail # PKG_NAME (default: qud) # VERSION (default: parsed from version.h) # ARCH (default: all) -# MAINTAINER (default: "Maintainer ") +# MAINTAINER (default: host-drivers.team "") # DESCRIPTION (default: generic description) # INSTALL_PREFIX (default: /opt/qcom/QUD) # OUTPUT_DIR (default: ./build) @@ -63,7 +63,7 @@ if [ -z "${VERSION:-}" ]; then fi ARCH="${ARCH:-all}" -MAINTAINER="${MAINTAINER:-Maintainer }" +MAINTAINER="${MAINTAINER:-host-drivers.team }" DESCRIPTION="${DESCRIPTION:-Qualcomm USB kernel drivers for QUD devices. Installs kernel driver sources and helper scripts, builds and loads the drivers during installation via qcom_drivers.sh.}" INSTALL_ROOT="${INSTALL_ROOT:-/opt/qcom/QUD}" INSTALL_PREFIX="${INSTALL_PREFIX:-$INSTALL_ROOT/build}" @@ -185,20 +185,6 @@ INSTALL_ROOT="$INSTALL_ROOT" INSTALL_PREFIX="$INSTALL_PREFIX" LOG_FILE="\$INSTALL_ROOT/qcom_kernel_install.log" -# Guard: qualcomm-userspace-driver must be removed before installing qud. -# (The control file already declares Conflicts/Breaks; this is a belt-and-braces -# check in case the user invoked `dpkg -i --force-conflicts` or similar.) -USERSPACE_STATUS="\$(dpkg-query -W -f='\${Status}' qualcomm-userspace-driver 2>/dev/null || true)" -if [ "\$USERSPACE_STATUS" = "install ok installed" ]; then - echo "ERROR: 'qualcomm-userspace-driver' is currently installed." >&2 - echo " The 'qud' kernel driver package conflicts with it and cannot be installed" >&2 - echo " alongside. Please remove it first and retry:" >&2 - echo " sudo dpkg -r qualcomm-userspace-driver" >&2 - echo " or (to resolve automatically):" >&2 - echo " sudo apt-get install ./qud_${VERSION}_${DEB_ARCH}.deb" >&2 - exit 1 -fi - mkdir -p "\$INSTALL_ROOT" || true # Remove any previous extracted build folder so we start fresh @@ -226,21 +212,61 @@ INSTALL_ROOT="$INSTALL_ROOT" INSTALL_PREFIX="$INSTALL_PREFIX" LOG_FILE="\$INSTALL_ROOT/qcom_kernel_install.log" -echo "[QUD] Ensuring script permissions..." | tee -a "\$LOG_FILE" +# LOG_HEADER() writes a visually distinct === frame around the stage name to the +# install log so the reader can tell where each stage starts. +LOG_HEADER() { + { + echo "" + echo "==================================================================" + echo "[QUD] \$1" + echo "==================================================================" + } >> "\$LOG_FILE" 2>&1 +} + +echo "[QUD] Ensuring script permissions..." >> "\$LOG_FILE" 2>&1 find "\$INSTALL_PREFIX" -type f -name '*.sh' -exec chmod +x {} \\; || true chmod +x "\$INSTALL_PREFIX/qcom_drivers.sh" 2>/dev/null || true chmod +x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" 2>/dev/null || true -USERSPACE_STATUS="\$(dpkg-query -W -f='\${Status}' qualcomm-userspace-driver 2>/dev/null || true)" -if [ "\$USERSPACE_STATUS" = "install ok installed" ]; then - echo "[QUD] qualcomm-userspace-driver is installed. Removing it before installing QUD kernel driver..." >> "\$LOG_FILE" 2>&1 - DEBIAN_FRONTEND=noninteractive dpkg --remove --force-remove-reinstreq qualcomm-userspace-driver >> "\$LOG_FILE" 2>&1 || \\ - DEBIAN_FRONTEND=noninteractive dpkg --purge --force-remove-reinstreq qualcomm-userspace-driver >> "\$LOG_FILE" 2>&1 || true -else - echo "[QUD] qualcomm-userspace-driver is not installed, skipping removal." >> "\$LOG_FILE" 2>&1 +# 'qualcomm-userspace-driver' is removed by dpkg itself before postinst runs, +# via the Conflicts/Replaces/Breaks fields declared in DEBIAN/control. +# This stage only records the outcome in the install log. +LOG_HEADER "Checking qualcomm-userspace-driver state" +USERSPACE_STATUS_RAW="\$(dpkg-query -W -f='\${Status}|\${Version}' qualcomm-userspace-driver 2>/dev/null || true)" +USERSPACE_STATUS_FIELD="\${USERSPACE_STATUS_RAW%%|*}" +USERSPACE_VERSION_FIELD="\${USERSPACE_STATUS_RAW##*|}" +USERSPACE_DPKG_EVENT="" + +if [ -r /var/log/dpkg.log ]; then + USERSPACE_DPKG_EVENT="\$(tail -n 200 /var/log/dpkg.log 2>/dev/null \\ + | grep -E '(remove|purge|status (config-files|not-installed|half-installed|half-configured)) qualcomm-userspace-driver' \\ + | tail -n 1 || true)" +fi + +case "\$USERSPACE_STATUS_FIELD" in + "deinstall ok config-files"|"deinstall ok half-configured"|"deinstall ok half-installed") + echo "[QUD] qualcomm-userspace-driver (\$USERSPACE_VERSION_FIELD) was just removed by dpkg via Conflicts/Replaces/Breaks." >> "\$LOG_FILE" 2>&1 + ;; + *) + if [ -n "\$USERSPACE_DPKG_EVENT" ]; then + echo "[QUD] qualcomm-userspace-driver was just removed by dpkg via Conflicts/Replaces/Breaks (from /var/log/dpkg.log: \$USERSPACE_DPKG_EVENT)." >> "\$LOG_FILE" 2>&1 + else + echo "[QUD] qualcomm-userspace-driver: not installed." >> "\$LOG_FILE" 2>&1 + fi + ;; +esac + +# Append the last few relevant lines of /var/log/dpkg.log +if [ -r /var/log/dpkg.log ]; then + USERSPACE_DPKG_TAIL="\$(tail -n 200 /var/log/dpkg.log 2>/dev/null | grep -E 'qualcomm-userspace-driver|qud:all' | tail -n 15 || true)" + if [ -n "\$USERSPACE_DPKG_TAIL" ]; then + echo "[QUD] /var/log/dpkg.log excerpt (last 15 qud / qualcomm-userspace-driver events):" >> "\$LOG_FILE" 2>&1 + echo "\$USERSPACE_DPKG_TAIL" >> "\$LOG_FILE" 2>&1 + fi fi # Uninstall any QUD driver previously installed via qpm-cli +LOG_HEADER "qpm-cli QUD uninstall (qud.internal / qud / qud.slt)" if command -v qpm-cli >/dev/null 2>&1; then QUD_INTERNAL_VERSION="\$(qpm-cli --info qud.internal 2>/dev/null | grep "Installed" | awk '{printf \$4}')" QUD_EXTERNAL_VERSION="\$(qpm-cli --info qud 2>/dev/null | grep "Installed" | awk '{printf \$4}')" @@ -266,7 +292,12 @@ else echo "[QUD] qpm-cli not available, skipping qpm-cli QUD uninstall." >> "\$LOG_FILE" 2>&1 fi -# Legacy QUD service cleanup +LOG_HEADER "Legacy QUD cleanup" +if [ -x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" ]; then + "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" uninstall >> "\$LOG_FILE" 2>&1 || true +fi + +LOG_HEADER "Legacy QUD service cleanup" QC_SYSTEMD_PATH=/etc/systemd/system if [ -f \$QC_SYSTEMD_PATH/QUDService.service ]; then systemctl daemon-reload >> "\$LOG_FILE" 2>&1 || true @@ -279,7 +310,7 @@ else echo "Error: Failed to delete \$QC_SYSTEMD_PATH/QUDService.service" >> "\$LOG_FILE" 2>&1 fi -# New QUD service cleanup +LOG_HEADER "New QUD service cleanup" QCOM_SYSTEMD_PATH=/etc/systemd/system QCOM_QUDSERVICE=qcom-qud.service if [ -f \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE ]; then @@ -293,17 +324,15 @@ else echo "Error: Failed to delete \$QCOM_SYSTEMD_PATH/\$QCOM_QUDSERVICE" >> "\$LOG_FILE" 2>&1 fi -if [ -x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" ]; then - "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" uninstall >> "\$LOG_FILE" 2>&1 || true -fi - # Ensure kernel headers are available for the running kernel before building modules. KREL="\$(uname -r)" +LOG_HEADER "Ensure kernel headers for \$KREL" if [ ! -d "/lib/modules/\$KREL/build" ]; then echo "[QUD] Kernel headers for \$KREL not found, attempting to install linux-headers-\$KREL..." >> "\$LOG_FILE" 2>&1 apt-get install -y "linux-headers-\$KREL" >> "\$LOG_FILE" 2>&1 || true fi +LOG_HEADER "Installing latest QUD driver via qcom_drivers.sh" echo "[QUD] Executing qcom_drivers.sh install from \$INSTALL_PREFIX..." >> "\$LOG_FILE" 2>&1 if [ -x "\$INSTALL_PREFIX/qcom_drivers.sh" ]; then (cd "\$INSTALL_PREFIX" && "\$INSTALL_PREFIX/qcom_drivers.sh" install) >> "\$LOG_FILE" 2>&1 \\ From af8aea2281b1543d90cd0e1965659f2289303e84 Mon Sep 17 00:00:00 2001 From: shasaror Date: Wed, 6 May 2026 12:05:33 +0530 Subject: [PATCH 3/4] added license Signed-off-by: shasaror --- src/linux/build-deb.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/linux/build-deb.sh b/src/linux/build-deb.sh index 3a249fd..83b51c5 100755 --- a/src/linux/build-deb.sh +++ b/src/linux/build-deb.sh @@ -1,3 +1,6 @@ +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + #!/usr/bin/env bash set -euo pipefail @@ -105,11 +108,6 @@ mkdir -p "$OUTPUT_DIR" chmod 0755 "$BUILDROOT/DEBIAN" chmod 0755 "$BUILDROOT$INSTALL_PREFIX" -# Pack everything located at qcom-usb-kernel-drivers/src/linux into the package build payload. -# Expected contents: InfParser Makefile qcom_drivers.sh qcom_serial qcom_usb qcom_usbnet -# README.md RELEASES.md sign version.h -# Exclude only: build/ (local output) and build-deb.sh (the packaging script itself). -# On install these are unpacked under /opt/qcom/QUD. echo "Copying driver sources from $SRC_DIR -> $BUILDROOT$INSTALL_PREFIX" shopt -s dotglob nullglob for entry in "$SRC_DIR"/*; do From 6d60bfbc3992db900f7784e4d1db406d1014966c Mon Sep 17 00:00:00 2001 From: shasaror Date: Wed, 6 May 2026 15:52:23 +0530 Subject: [PATCH 4/4] Minor fixes to improve logging and upgrade feature Signed-off-by: shasaror --- src/linux/build-deb.sh | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/linux/build-deb.sh b/src/linux/build-deb.sh index 83b51c5..9c2c499 100755 --- a/src/linux/build-deb.sh +++ b/src/linux/build-deb.sh @@ -228,17 +228,25 @@ chmod +x "\$INSTALL_PREFIX/legacy/installer/QcDevDriver.sh" 2>/dev/null || true # 'qualcomm-userspace-driver' is removed by dpkg itself before postinst runs, # via the Conflicts/Replaces/Breaks fields declared in DEBIAN/control. -# This stage only records the outcome in the install log. +# This stage will only display status and store dpkg events in the install log. LOG_HEADER "Checking qualcomm-userspace-driver state" USERSPACE_STATUS_RAW="\$(dpkg-query -W -f='\${Status}|\${Version}' qualcomm-userspace-driver 2>/dev/null || true)" USERSPACE_STATUS_FIELD="\${USERSPACE_STATUS_RAW%%|*}" USERSPACE_VERSION_FIELD="\${USERSPACE_STATUS_RAW##*|}" USERSPACE_DPKG_EVENT="" +USERSPACE_DPKG_TAIL="" if [ -r /var/log/dpkg.log ]; then - USERSPACE_DPKG_EVENT="\$(tail -n 200 /var/log/dpkg.log 2>/dev/null \\ - | grep -E '(remove|purge|status (config-files|not-installed|half-installed|half-configured)) qualcomm-userspace-driver' \\ - | tail -n 1 || true)" + CURRENT_TXN="\$(awk '/ startup /{buf=""} {buf=buf \$0 ORS} END{printf "%s", buf}' /var/log/dpkg.log 2>/dev/null || true)" + if [ -n "\$CURRENT_TXN" ]; then + USERSPACE_DPKG_EVENT="\$(printf '%s' "\$CURRENT_TXN" \\ + | grep -E '(^.* (remove|purge) qualcomm-userspace-driver:|^.* status (config-files|not-installed|half-installed|half-configured) qualcomm-userspace-driver:)' \\ + | tail -n 1 || true)" + fi +fi + +if [ -r /var/log/dpkg.log ]; then + USERSPACE_DPKG_TAIL="\$(grep -E 'qud:all|qualcomm-userspace-driver' /var/log/dpkg.log 2>/dev/null | tail -n 15 || true)" fi case "\$USERSPACE_STATUS_FIELD" in @@ -247,20 +255,18 @@ case "\$USERSPACE_STATUS_FIELD" in ;; *) if [ -n "\$USERSPACE_DPKG_EVENT" ]; then - echo "[QUD] qualcomm-userspace-driver was just removed by dpkg via Conflicts/Replaces/Breaks (from /var/log/dpkg.log: \$USERSPACE_DPKG_EVENT)." >> "\$LOG_FILE" 2>&1 + echo "[QUD] qualcomm-userspace-driver was just removed by dpkg via Conflicts/Replaces/Breaks in current installation (from /var/log/dpkg.log: \$USERSPACE_DPKG_EVENT)." >> "\$LOG_FILE" 2>&1 else - echo "[QUD] qualcomm-userspace-driver: not installed." >> "\$LOG_FILE" 2>&1 + echo "[QUD] qualcomm-userspace-driver was not installed this time, so dpkg Conflicts/Replaces/Breaks did not remove anything." >> "\$LOG_FILE" 2>&1 fi ;; esac # Append the last few relevant lines of /var/log/dpkg.log -if [ -r /var/log/dpkg.log ]; then - USERSPACE_DPKG_TAIL="\$(tail -n 200 /var/log/dpkg.log 2>/dev/null | grep -E 'qualcomm-userspace-driver|qud:all' | tail -n 15 || true)" - if [ -n "\$USERSPACE_DPKG_TAIL" ]; then - echo "[QUD] /var/log/dpkg.log excerpt (last 15 qud / qualcomm-userspace-driver events):" >> "\$LOG_FILE" 2>&1 - echo "\$USERSPACE_DPKG_TAIL" >> "\$LOG_FILE" 2>&1 - fi +if [ -n "\$USERSPACE_DPKG_TAIL" ]; then + echo "" >> "\$LOG_FILE" 2>&1 + echo "[QUD] /var/log/dpkg.log excerpt (last few instances of qud / qualcomm-userspace-driver events from /var/log/dpkg.log):" >> "\$LOG_FILE" 2>&1 + printf '%s\n' "\$USERSPACE_DPKG_TAIL" | sed 's/^/[dpkg logs] /' >> "\$LOG_FILE" 2>&1 fi # Uninstall any QUD driver previously installed via qpm-cli @@ -381,7 +387,7 @@ INSTALL_PREFIX="$INSTALL_PREFIX" LOG_FILE="\$INSTALL_ROOT/qcom_kernel_uninstall.log" case "\$1" in - remove|purge|upgrade|disappear) + remove|purge|disappear) echo "[QUD] Cleaning up \$INSTALL_ROOT/qcom_drivers.sh and \$INSTALL_PREFIX ..." >> "\$LOG_FILE" 2>&1 || true rm -f "\$INSTALL_ROOT/qcom_drivers.sh" >> "\$LOG_FILE" 2>&1 || true rm -rf "\$INSTALL_PREFIX" >> "\$LOG_FILE" 2>&1 || true